Vue入门

56 阅读4分钟

一心想做后端,对于前端是不太乐意去做的,但基本的了解还是需要的。去年Java Web课程作业项目,就是前后端全包,不过那时前端用的还是传统的JSP,着实感觉不太舒服,学过SpringBoot了,使用了Thymeleaf,体会到开发的便捷,认识到了前后端分离,越发感到之前的开发模式是该被取代了。

终于有机会认识前端的一些东西了,本来我的这个博客框架就与前端脱不开关系,Node.jsnpm这些都是我博客搭建的基础,这次来简单入门Vue

参考

提要

必要知识:前端三剑客(HTML、CSS、JS)+ Ajax

开发环境:VSCode + Live Server、Chrome

推荐VSCode插件:Auto Close Tag、Auto Rename Tag、Vetur、根据需要参考 VScode插件推荐(全面)

Live Server 简单使用说明:使用Live Server主要原因是开启本地服务并在保存时刷新页面,方便调试,在VSCode需要使用Live Server 页面右键选择Open with Live ServerStop Live Server

最后会放上我的全部源码链接,希望有帮助。

安装

官方说的非常清楚了新手入门使用

<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="https://cdn.staticaly.com/npm/vue/dist/vue.js"></script>

<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.staticaly.com/npm/vue"></script>

认识Vue

Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统:

官方示例

<div id="app">
  {{ message }}
</div>

var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
})

注意上面是在html中,下面在js中

简单理解,声明app通过eldiv-app绑定,这时div-appapp-Vue同属于一个域,data类似声明数据(key-value),通过{{x}},取值

基本

**v-text:**显示文本,替换问题

<div id="text">
    {{message}}
    <h2 v-text="message+'!'">测试拼接</h2> <!-- 结果:message! -->
    <h2 v-text="info+'?'">测试拼接</h2>	<!-- 结果:info? -->
    <h2>拼接{{message}}</h2> <!-- 结果:拼接message -->
</div>
	<!-- 开发环境版本,包含了有帮助的命令行警告 -->
    <script src="https://cdn.staticaly.com/npm/vue/dist/vue.js"></script>
    <script>
        var text=new Vue({
            el:"#text",
            data:{
                message:"text显示",
                info:"信息展示"
            }
        })
    </script>

**v-html:**显示文本,若是html元素则解析

<div id="html">	<!-- content为<a>超链接 -->
    <p v-html="content"></p>	<!-- 解析成超链接 -->
    <p v-text="content"></p>	<!-- 解析成超链接文本 -->
</div>
	<!-- 开发环境版本,包含了有帮助的命令行警告 -->
    <script src="https://cdn.staticaly.com/npm/vue/dist/vue.js"></script>
    <script>
        var html=new Vue({
            el:"#html",
            data:{
                content:"<a href='https:/wnhyang.github.io'>博客</a>"
            }
        })
    </script>

**v-on:**事件处理,可用@代替,函数如下methods部分,在Chrome检查控制台查看

<div id="on">
    <input type="button" value="v-on指令" v-on:click="doIt"/>
    <input type="button" value="@指令" v-on:click="doIt"/>
    <input type="button" value="双击" @dblclick="doIt"/>
    <h2 @click="changeFood">{{food}}</h2>
</div>
	<!-- 开发环境版本,包含了有帮助的命令行警告 -->
    <script src="https://cdn.staticaly.com/npm/vue/dist/vue.js"></script>
    <script>
        var on=new Vue({
            el:"#on",
            data:{
                food:"西红柿"
            },
            methods:{
                doIt:function(){
                    alert("doit");
                },
                changeFood(){
                    console.log(this.food);
                    this.food+="如果!"
                }
            },
        })
    </script>

**v-show:**状态,本质改变了显示状态

<div id="show">
    <input type="button" value="切换显示状态" @click="changeIsShow">
    <input type="button" value="累加年龄" @click="addAge">
    <img v-show="isShow" width="100" src="./img/123.jpg" alt="">
    <img v-show="age>=18" width="100" src="./img/123.jpg" alt="">
</div>
	<!-- 开发环境版本,包含了有帮助的命令行警告 -->
    <script src="https://cdn.staticaly.com/npm/vue/dist/vue.js"></script>
    <script>
        var show=new Vue({
            el:"#show",
            data:{
                isShow:false,
                age:17
            },
            methods:{
                changeIsShow:function(){
                    this.isShow=!this.isShow;
                },
                addAge:function(){
                    this.age++;
                }
            },
        })
    </script>

**v-if:**状态,直接在或不在,区分与v-show,发现v-if直接影响整个元素,不是v-show改变状态

<div id="ifapp">
    <input type="button" value="切换显示" @click="toggleIsShow">
    <p v-if="isShow">v-if好吗</p>
    <p v-show="isShow">v-show好吗</p>
    <h2 v-if="temperature>=35">热死了</h2>
</div>
	<!-- 开发环境版本,包含了有帮助的命令行警告 -->
    <script src="https://cdn.staticaly.com/npm/vue/dist/vue.js"></script>
    <script>
        var ifapp=new Vue({
            el:"#ifapp",
            data:{
                isShow:false,
                temperature:40
            },
            methods:{
                toggleIsShow:function(){
                    this.isShow=!this.isShow;
                }
            },
        })
    </script>

**v-bind:**绑定,作用于元素属性,可简写为:属性,三元表达式或"{active:isActive}",推荐后者

    <style>
        .active{
            border: 1px solid red;
        }
    </style>

<div id="bind">
    <img width="100" v-bind:src="imgSrc" alt="">
    <br/>
    <img width="100" :src="imgSrc" :title="imgTitle+'!!!'" alt="" :class="isActive?'active':''" @click="toggleActive">
    <br/>
    <img width="100" :src="imgSrc" :title="imgTitle+'!!!'" alt="" :class="{active:isActive}" @click="toggleActive">
</div>

	<!-- 开发环境版本,包含了有帮助的命令行警告 -->
    <script src="https://cdn.staticaly.com/npm/vue/dist/vue.js"></script>
    <script>
        var bind=new Vue({
            el:"#bind",
            data:{
                imgSrc:"https://cn.vuejs.org/images/logo.png",
                imgTitle:"Vue",
                isActive:false
            },
            methods:{
                toggleActive(){
                    this.isActive=!this.isActive;
                }
            }
        })
    </script>

**v-for:**循环,看下示例即可

<div id="forapp">
    <input type="button" value="添加数据" @click="add"/>
    <input type="button" value="移除数据" @click="remove"/>
    <ul>
        <li v-for="(item,index) in arr">
            {{index}}Vue:{{item}}
        </li>
    </ul>
    <h2 v-for="item in vegetables" v-bind:title="item.name">
        {{item.name}}
    </h2>
</div>

	<!-- 开发环境版本,包含了有帮助的命令行警告 -->
    <script src="https://cdn.staticaly.com/npm/vue/dist/vue.js"></script>
    <script>
        var forapp=new Vue({
            el:"#forapp",
            data:{
                arr:["北京","上海","广州","深圳"],
                vegetables:[
                    {name:"西红柿炒鸡蛋"},
                    {name:"凉拌黄瓜"}
                ]
            },
            methods:{
                add:function(){
                    this.vegetables.push({name:"炒土豆丝"});
                },
                remove:function(){
                    this.vegetables.shift();
                }
            }
        })
    </script>

**v-model:**双向绑定,如下,div-modelapp与modelapp-Vue域同步改变

<div id=modelapp>
    <input type="button" value="修改message" @click="setM"/>
    <input type="text" v-model="message" @keyup.enter="getM"/>
    <h2>{{message}}</h2>
</div>

	<!-- 开发环境版本,包含了有帮助的命令行警告 -->
    <script src="https://cdn.staticaly.com/npm/vue/dist/vue.js"></script>
    <script>
        var modelapp=new Vue({
            el:"#modelapp",
            data:{
                message:"Vue"
            },
            methods:{
                getM:function(){
                    alert(this.message);
                },
                setM:function(){
                    this.message="VueDemo";
                }
            },
        })
    </script>

实例

计数器

<div id="counter">
    <button @click="sub">-</button>
    <span>{{num}}</span>
    <button @click="add">+</button>
</div>

	<!-- 开发环境版本,包含了有帮助的命令行警告 -->
    <script src="https://cdn.staticaly.com/npm/vue/dist/vue.js"></script>
    <script>
        var counter=new Vue({
            el:"#counter",
            data:{
                num:1
            },
            methods:{
                add:function(){
                    console.log('add');
                    if(this.num<10){
                        this.num++;
                    }else{
                        alert('别点了,最大了');
                    }
                },
                sub:function(){
                    console.log('sub');
                    if(this.num>0){
                        this.num--;
                    }else{
                        alert('别点了,最小了');
                    }
                }
            },
        })
    </script>

记事本

    <div id="todoapp">
        <header>
            <h1>
                Vue记事本
            </h1>
            <input v-model="inputValue" @keyup.enter="add" type="text" placeholder="输入"/>
        </header>

        <section class="main">
            <ul>
                <li v-for="(item,index) in list">
                    <div>
                        <span>{{index+1}}.</span>
                        <label>{{item}}</label>
                        <button @click="remove(index)">x</button>
                    </div>
                    
                </li>
            </ul>
        </section>

        <footer>
            <span v-if="list.length!=0">总数:{{list.length}}</span>
            <button @click="clear" v-show="list.length!=0">Clear</span>
        </footer>
    </div>

	<!-- 开发环境版本,包含了有帮助的命令行警告 -->
    <script src="https://cdn.staticaly.com/npm/vue/dist/vue.js"></script>
    <script>
        var todoapp=new Vue({
            el:"#todoapp",
            data:{
                list:["写代码","吃饭","睡觉"],
                inputValue:"content",
            },
            methods:{
                add:function(){
                    this.list.push(this.inputValue);
                },
                remove:function(index){
                    console.log("删除");
                    console.log(index);
                    this.list.splice(index,1)
                },
                clear:function(){
                    this.list=[];
                }
            }
        })
    </script>

axios

简单的说:Ajax的封装版,简单实用

<input type="button" value="get" class="get"/>
<input type="button" value="post" class="post"/>

    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script>
        // 用的是js呢
        document.querySelector(".get").onclick = function() {
                axios.get('https://autumnfish.cn/api/joke/list?num=6').then(function(response) {
                    console.log(response.data); //好像是data吧
                }, function(error) {
                    console.log(error);
                })
            }

        document.querySelector(".post").onclick = function() {
            axios.post('https://autumnfish.cn/api/user/reg',{username:"西兰花10"})
            .then(function(response){
                console.log(response);
            },function(error) {
                console.log(error);
            })
        }
    </script>

用到在线API:autumnfish.cn/api/joke/li… 获取6条笑话,autumnfish.cn/api/user/re… 注册用户

vue-axios

<div id="app">
    <input type="button" value="获取笑话" @click="getJoke"/>
    <p>{{joke}}</p>
</div>

    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <!-- 开发环境版本,包含了有帮助的命令行警告 -->
    <script src="https://cdn.staticaly.com/npm/vue/dist/vue.js"></script>

    <script>
        var app=new Vue({
            el:"#app",
            data:{
                joke:"笑话"
            },
            methods:{
                getJoke:function(){
                    console.log(this.joke);
                    var that=this;
                    axios.get('https://autumnfish.cn/api/joke')
                    .then(function(response){
                        console.log(response.data);
                        that.joke=response.data;
                        // this.joke=response.data;
                    },function(error){
                        console.log(error);
                    })
                }
            }
        })
    </script>

仔细看:this,that

实例

查天气

    <div id="app">
        <input @keyup.enter="searchWeather" v-model="city" type="text" placeholder="输入地区查天气"/>
        <button @click="searchWeather">查询</button>
        <div>
            <a href="javascript:;" @click="changeCity('北京')">北京</a>
            <a href="javascript:;" @click="changeCity('上海')">上海</a>
            <a href="javascript:;" @click="changeCity('广州')">广州</a>
            <a href="javascript:;" @click="changeCity('深圳')">深圳</a>
        </div>
        <ul>
            <li v-for="item in weatherList">
                {{item.type}}
                <b>{{item.low}}</b>
                ~
                <b>{{item.high}}</b>

                <span>{{item.date}}</span>
            </li>
        </ul>
    </div>
    

    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <!-- 开发环境版本,包含了有帮助的命令行警告 -->
    <script src="https://cdn.staticaly.com/npm/vue/dist/vue.js"></script>

    <script src="./js/vue-weather.js"></script>

var app=new Vue({
    el:"#app",
    data:{
        city:"",
        weatherList:[],
    },
    methods:{
        searchWeather:function(){
            // console.log('天气查询');
            // console.log(this.city);
            var that=this;
            axios.get('http://wthrcdn.etouch.cn/weather_mini?city='+this.city)
            .then(function(response){
                console.log(response.data.data.forecast);
                that.weatherList=response.data.data.forecast;
            },function(error){
                console.log(error);
            })
        },
        changeCity:function(city){
            this.city=city;
            this.searchWeather();
        }
    },
})

用到API:wthrcdn.etouch.cn/weather_min… 查某地近几天天气,通过console.log(),查看返回数据,找到需要的数据

音乐播放器

    <div id="app">
        <div v-show="!isShow">
            <input @keyup.enter="searchMusic" v-model="query" type="text" placeholder="输入"/>
            <button @click="searchMusic">查询</button>
            <ul>
                <li v-for="item in musicList">
                    <a @click="playMusic(item.id)">+</a>
                    <b>{{item.name}}</b>
                    <span v-if="item.mvid!=0" @click="playMV(item.mvid)"><i>mv</i></span>
                </li>
            </ul>
            <div>
                <b :class="{playing:isPlaying}">播放中</b>
                <img width="200" :src="musicCover"/>
            </div>
            <div>
                <audio ref='audio' :src="musicUrl" @play="play" @pause="pause" controls autoplay loop ></audio>
            </div>
            <div>
                <dl v-for="item in hotComments">
                    <dt><img width="50" :src="item.user.avatarUrl"></dt>
                    <dd><b>{{item.user.nickname}}</b></dd>
                    <dd>{{item.content}}</dd>
                </dl>
            </div>
        </div>
        
        <div v-if="isShow">
            <video :src="mvUrl" controls="controls"></video>
            <div @click="hide">hide</div>
        </div>
    </div>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <!-- 开发环境版本,包含了有帮助的命令行警告 -->
    <script src="https://cdn.staticaly.com/npm/vue/dist/vue.js"></script>

    <script src="./js/vue-music.js"></script>

var app=new Vue({
    el:"#app",
    data:{
        // 查询关键字
        query:"",
        // 歌曲数据
        musicList:[],
        // 歌曲地址
        musicUrl:"",
        // 歌曲图片
        musicCover:"",
        // 歌曲评论
        hotComments:[],
        // 动画播放状态
        isPlaying:false,
        // 遮罩层显示状态
        isShow:false,
        // MV地址
        mvUrl:""
    },
    methods:{
        searchMusic:function(){
            // console.log(this.query);
            var that=this;
            axios.get('https://autumnfish.cn/search?keywords='+this.query)
            .then(function(response){
                // console.log(response);
                that.musicList=response.data.result.songs;
                console.log(response.data.result.songs)
            },function(error){
                console.log(error);
            })
        },
        playMusic:function(musicId){
            // console.log(musicId);
            var that=this;
            // 歌曲地址
            axios.get('https://autumnfish.cn/song/url?id='+musicId)
            .then(function(response){
                // console.log(response);
                console.log(response.data.data[0].url);
                that.musicUrl=response.data.data[0].url;
            },function(error){
                console.log(error);
            })
            // 歌曲图片
            axios.get('https://autumnfish.cn/song/detail?ids='+musicId)
            .then(function(response){
                // console.log(response);
                console.log(response.data.songs[0].al.picUrl);
                that.musicCover=response.data.songs[0].al.picUrl;
            },function(error){
                console.log(error);
            })
            // 歌曲评论
            axios.get('https://autumnfish.cn/comment/hot?type=0&id='+musicId)
            .then(function(response){
                // console.log(response);
                console.log(response.data.hotComments);
                that.hotComments=response.data.hotComments;
            },function(error){
                console.log(error);
            })
        },
        play:function(){
            console.log("play");
            this.isPlaying=true;
        },
        pause:function(){
            console.log("pause");
            this.isPlaying=false;
        },
        playMV:function(mvid){
            var that=this;
            axios.get('https://autumnfish.cn/mv/url?id='+mvid)
            .then(function(response){
                // console.log(response);
                console.log(response.data.data.url);
                that.isShow=true;
                that.mvUrl=response.data.data.url;
            },function(error){
                console.log(error);
            })
        },
        hide:function(){
            this.isShow=false;
        }
    }
})

用到API:

以上皆为网易云提供的API,感觉还是很奇妙的,使用那些在线开放的API即可实现看似很复杂的东西,让我对前端的印象有点改观

源码链接

总结

学了就是为了用,目前几乎所有开源的优秀项目,总是在readme中写明自己用到了那些技术,前后端分离项目也多的很,往往都会看到自己没有学过甚至是没有了解和听说的,对于学习那些优秀项目阻碍还是很大了,终于算是入门Vue了吧,接下来可能会做一些有趣的项目。