一心想做后端,对于前端是不太乐意去做的,但基本的了解还是需要的。去年Java Web
课程作业项目,就是前后端全包,不过那时前端用的还是传统的JSP
,着实感觉不太舒服,学过SpringBoot
了,使用了Thymeleaf
,体会到开发的便捷,认识到了前后端分离,越发感到之前的开发模式是该被取代了。
终于有机会认识前端的一些东西了,本来我的这个博客框架就与前端脱不开关系,Node.js
、npm
这些都是我博客搭建的基础,这次来简单入门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 Server
或Stop Live Server
。
最后会放上我的全部源码链接,希望有帮助。
安装
官方说的非常清楚了新手入门使用
1 2
| <script src="https://cdn.staticaly.com/npm/vue/dist/vue.js"></script>
|
或
1 2
| <script src="https://cdn.staticaly.com/npm/vue"></script>
|
认识Vue
Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM
的系统:
官方示例
1 2 3
| <div id="app"> {{ message }} </div>
|
1 2 3 4 5 6
| var app = new Vue({ el: '#app', data: { message: 'Hello Vue!' } })
|
注意上面是在html中,下面在js中
简单理解,声明app
通过el
与div-app
绑定,这时div-app
与app-Vue
同属于一个域,data
类似声明数据(key-value),通过{{x}}
,取值
基本
v-text:显示文本,替换问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <div id="text"> {{message}} <h2 v-text="message+'!'">测试拼接</h2> <h2 v-text="info+'?'">测试拼接</h2> <h2>拼接{{message}}</h2> </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元素则解析
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <div id="html"> <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检查控制台查看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <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:状态,本质改变了显示状态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <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改变状态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <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}",推荐后者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <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:循环,看下示例即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| <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域同步改变
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <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>
|
实例
计数器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| <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>
|
记事本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| <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的封装版,简单实用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <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> document.querySelector(".get").onclick = function() { axios.get('https://autumnfish.cn/api/joke/list?num=6').then(function(response) { console.log(response.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:https://autumnfish.cn/api/joke/list?num=6
获取6条笑话,https://autumnfish.cn/api/user/reg 注册用户
vue-axios
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <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; },function(error){ console.log(error); }) } } }) </script>
|
仔细看:this,that
实例
查天气
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <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>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| var app=new Vue({ el:"#app", data:{ city:"", weatherList:[], }, methods:{ searchWeather:function(){ 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:http://wthrcdn.etouch.cn/weather_mini?city=
查某地近几天天气,通过console.log(),查看返回数据,找到需要的数据
音乐播放器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| <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>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| var app=new Vue({ el:"#app", data:{ query:"", musicList:[], musicUrl:"", musicCover:"", hotComments:[], isPlaying:false, isShow:false, mvUrl:"" }, methods:{ searchMusic:function(){ var that=this; axios.get('https://autumnfish.cn/search?keywords='+this.query) .then(function(response){ that.musicList=response.data.result.songs; console.log(response.data.result.songs) },function(error){ console.log(error); }) }, playMusic:function(musicId){ var that=this; axios.get('https://autumnfish.cn/song/url?id='+musicId) .then(function(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.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.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.data.data.url); that.isShow=true; that.mvUrl=response.data.data.url; },function(error){ console.log(error); }) }, hide:function(){ this.isShow=false; } } })
|
用到API:
- https://autumnfish.cn/search?keywords= 根据关键词查询
- https://autumnfish.cn/song/url?id= 根据歌曲id查询具体歌曲Url
- https://autumnfish.cn/song/detail?ids=
根据歌曲id查询具体歌曲信息
- https://autumnfish.cn/comment/hot?type=0&id=
根据歌曲id查询具体歌曲热门评论
- https://autumnfish.cn/mv/url?id= 根据歌曲mvid查询具体歌曲mvUrl
以上皆为网易云提供的API,感觉还是很奇妙的,使用那些在线开放的API即可实现看似很复杂的东西,让我对前端的印象有点改观
源码链接
总结
学了就是为了用,目前几乎所有开源的优秀项目,总是在readme中写明自己用到了那些技术,前后端分离项目也多的很,往往都会看到自己没有学过甚至是没有了解和听说的,对于学习那些优秀项目阻碍还是很大了,终于算是入门Vue了吧,接下来可能会做一些有趣的项目。