日Vue

概述:Vue

[TOC]

1.安装Vue

(1)使用script引入

下载地址:https://cn.vuejs.org/v2/guide/installation.html

分为开发版本和生产版本(不提供警告信息)

1
<script src="vue.js" type="text/javascript" charset="utf-8"></script>

(2)使用CDN

CDN 内容分发网络:content delivery network

CDN可以通过不同的域名来加载文件,从而使下载文件的并发连接数大大增加。

1
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

生产环境:

1
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>

2.Hello,Vue!

1
2
3
4
5
6
7
8
9
10
11
12
13
<body>
<div id="app">
{{message}}
</div>
<script type="text/javascript">
var app = new Vue({// 声明式开发方式
el:'#app',//el表示element,用于挂载要管理的元素
data:{//data用于保存数据
message:'Hello Vue!',
},
})
</script>
</body>

※ 大括号内可以使用运算符,例如NaN、NaN等

3.MVVM

MVVM(Model–view–viewmodel)是一种软件架构模式。

Vue的MVVM中:

(1)View层:视图层,即DOM层,展示前端界面信息

(1)Model层:数据层

(1)VueModel层:视图模型层,实现Data Binding,即数据绑定,将Model改变实时反映到View中,另一方面实现了DOM Listener,即DOM监听,当DOM发生事件(点击;滚动;touch等)改变对应的Data。

4.Vue生命周期

5.指令

(1)v-once

使用<v -once>后内插值不允许被修改,永不更改的数据值,使用频率极低

1
<h2 v-once>{{message}}</h2>

(2)v-html

类似于超链接

1
2
3
4
5
6
7
8
9
10
11
<div id="app">
<h2 v-html="mylink"></h2>
</div>
<script type="text/javascript">
var vm = new Vue({
el : "#app",
data : {
mylink : '<a href="http://www.baidu.com">百度一下</a>'
},
});
</script>

(3)v-text

类似于Mustache,不同之处在于v-text标签内不能插入新的内容

1
2
3
4
<div id="app">
<h2>{{message}}新的插入内容</h2>
<h2 v-text="message">该部分插入内容无效</h2>
</div>

(4)v-pre

用于跳过元素和子元素的编译过程,显示原本Mustache的语法

1
2
3
4
5
6
7
8
9
10
11
12
<div id="app">
<h2>{{message}}</h2>
<h2 v-pre>{{message}}</h2>
</div>
<script type="text/javascript">
var vm = new Vue({
el : "#app",
data : {
message : 'testing'
},
});
</script>
1
2
testing
{{message}}

(5)v-cloak

在Mustache标签还未被解析前的表示方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<head>
<style>
[v-cloak]{
display:none;//即在未解析前不显示
}
</style>
</head>

<div id="app" v-cloak>
<h2>{{message}}</h2>
<h2 v-pre>{{message}}</h2>
</div>
<script type="text/javascript">
var vm = new Vue({
el : "#app",
data : {
message : 'testing'
},
});
</script>

(6)v-bind

动态绑定属性

v-bind:src=“imgSrc” —-简写—-> :src=”imgSrc”

:title

:class

1
2
3
4
5
6
7
8
9
10
11
12
13
<div id="app">
<a v-bind:href="link">官网</a>
<!-- <img v-bind:src="url"/> -->
</div>
<script type="text/javascript">
let app = new Vue({
el : "#app",
data : {
link : 'http://www.baidu.com',
// url : ''
}
})
</script>

在class上的应用(组件样式动态)

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
<style>
.active{
color: red;
}
.line{
font-size:10px;
}
</style>
<body>
<div id="app">
<a v-bind:href="link">官网</a>
<!-- <img v-bind:src="url"/> -->
<h2 v-bind:class="{active : isActive}">方式一:{{message}}</h2>
<h2 :class="{active : isActive}">方式二:{{message}}</h2>
<h2 :class="{active : isActive, line: isActive}">{{message}}(包含多个样式)</h2>
<h2 v-bind:class="getClasses()">方式三:{{message}}</h2>
<h2 :style="{fontSize:fsz + 'px'}">方式四:{{message}}</h2>
<button v-on:click="btnClick">按钮</button>
</div>
<script type="text/javascript">
let app = new Vue({
el : "#app",
data : {
link : 'http://www.baidu.com',
// url : ''
message:'Abc',
isActive:false,
fsz:'50'
},
methods:{
btnClick : function(){
this.isActive = !this.isActive
},
getClasses : function(){
return {active : this.isActive, line: this.isActive}
}
}
})
</script>
</body>

(7)v-on

绑定事件

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="app">
<h2>当前计数:{{counter}}</h2>
<!-- <button v-on:click="counter++">+</button> -->
<!-- <button v-on:click="counter--">-</button> -->
<button v-on:click="add">+</button>
<button v-on:click="sub">-</button>
<!-- @click是v-on:click的语法糖(简写),作用一致 -->
<!-- @dblclick是双击事件,相比于@click需要连续点击2次-->
</div>
<script type="text/javascript">
var vm = new Vue({
el : "#app",
data : {
counter : 0
},
methods:{
add:function(){
this.counter++;//若不添加this.则会寻找全局变量(无效)
},
sub:function(){
this.counter--;
},
}
});
</script>

传递自定义参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div id="app">
<p>方式1:回车弹框</p>
<input type='text' v-model="content" @keyup.enter="alert(content)"><!--自动更新变量-->
<p>方式2:点击弹框</p>
<button @click="alert(content)">按钮</button>
</div>
<script type="text/javascript">
var vm = new Vue({
el : "#app",
data : {
content:'',
},
methods:{
alert:function(p1){
alert(p1)
}
}
});
</script>

(8)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
26
27
28
29
<body>
<div id="app">
<h2 v-show="ifshow">{{firstName+' '+lastName}}</h2>
<button @click="showname">{{state}}名字</button>
</div>
<script type="text/javascript">
var app = new Vue({// 声明式开发方式
el:'#app',//el表示element,用于挂载要管理的元素
data:{//data用于保存数据
firstName:'zhang',
lastName:'san',
ifshow:true,
state:'隐藏'
},
methods:{
showname:function(){
this.ifshow=!this.ifshow;
if (this.state=='显示'){
this.state = '隐藏'
}
else{
this.state = '显示'
}

}
}
})
</script>
</body>

(9)v-if

类似于v-show,取值为true或者false

(10)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
<div id="app">
<ul>
<li v-for="(item,index) in movies">{{index+1}}:{{item}}</li>
<!--item in movies (可省略index)-->
<button @click="add">添加</button>
<button @click="sub">减少</button>
</ul>
</div>
<script type="text/javascript">
var vm = new Vue({
el : "#app",
data : {
movies : ['盗梦空间','阿凡达','素媛'],
},
methods:{
add:function(){
this.movies.push('新的电影')
},
sub:function(){
this.movies.shift()//删除头元素
}
}
});
</script>

(11)v-model

获取和设置表单元素的值(双向数据绑定),代码可参考v-on-传递自定义参数。

7.计算属性

computed相比于methods而言,计算属性会进行缓存,多次使用时,计算属性只会使用一次。

字符串拼接

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
<body>
<div id="app">
<h2>{{firstName + ' ' + lastName}}</h2>
<h2>{{getFullname()}}</h2>
<h2>{{fullName}}</h2>
</div>
<script type="text/javascript">
var app = new Vue({// 声明式开发方式
el:'#app',//el表示element,用于挂载要管理的元素
data:{//data用于保存数据
firstName:'zhang',
lastName:'san'
},
// 计算属性()
computed:{
fullName:function(){
return this.firstName + ' ' + this.lastName
}
},
methods:{
getFullname(){
return this.firstName + ' ' + this.lastName
}
}
})
</script>
</body>

数组的数值统计

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
<body>
<div id="app">
<h2>{{firstName + ' ' + lastName}}</h2>
<h2>{{getFullname()}}</h2>
<h2>{{fullName}}</h2>
<h2>{{totalPrice}}</h2>
</div>
<script type="text/javascript">
var app = new Vue({// 声明式开发方式
el:'#app',//el表示element,用于挂载要管理的元素
data:{//data用于保存数据
firstName:'zhang',
lastName:'san',
books:[
{id:1,name:'aa',price:39},
{id:2,name:'bb',price:100},
{id:3,name:'cc',price:22},
{id:4,name:'dd',price:9}
]
},
// 计算属性()
computed:{
fullName:function(){
return this.firstName + ' ' + this.lastName
},
totalPrice:function(){
let result = 0
for (let i=0;i< this.books.length;i++){
result +=this.books[i].price
}
return result
}
},
methods:{
getFullname(){
return this.firstName + ' ' + this.lastName
}
}
})
</script>
</body>

getter和setter,通常只实现getter方法(只读属性),getter是对上述fullName的另一种详细表达,通常使用上述的fullName即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<body>
<div id="app">
<h2>{{fullName}}</h2>
</div>
<script type="text/javascript">
var app = new Vue({// 声明式开发方式
el:'#app',//el表示element,用于挂载要管理的元素
data:{//data用于保存数据
firstName:'zhang',
lastName:'san'
},
// 计算属性()
computed:{
fullName:{
get:function(){
return this.firstName + ' ' + this.lastName
},
set:function(){
}
},
},
})
</script>
</body>

8.实践—图片轮播

第一幅图不显示左侧按钮;最后一幅图不显示右侧按钮

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
<body>
<div id="app">
<a href="#" @click="prev" v-show="index!=0">前一张</a>
<img :src="imgArr[index]" width="200px">
<a href="#" @click="next" v-if="index!=imgArr.length-1">后一张</a>
</div>
<script type="text/javascript">
var app = new Vue({// 声明式开发方式
el:'#app',//el表示element,用于挂载要管理的元素
data:{//data用于保存数据
imgArr:['images/1.jpg','images/2.jpg','images/3.jpg','images/4.jpg'],
index:0,
first:false,
last:true
},
methods:{
prev:function(){
this.index -=1
},
next:function(){
this.index +=1
}
}
})
</script>
</body>

9.实践—记事本

功能:1新增todo项;2删除todo项;3统计todo项;4清空todo项;5隐藏todo项目数及清空按钮

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="todolist">
<input type="text" v-model="content" autofocus="autofocus" autocomplete="off" @keyup.enter="add">

<ul v-for="(item,index) in list">
<!-- autofocus为是否自动获取光标位置;autocomplete为是否保留输入框历史记录-->
<li>
{{index+1}}. {{item}}
<button @click="remove(index)">删除</button>
</li>
</ul>
<p>
<span v-if="list.length!=0">
<strong>todo项共计:{{list.length}}</strong>
<button @click="removeall">清空</button>
</span>
</p>
</div>
<script type="text/javascript">
var app = new Vue({// 声明式开发方式
el:'#todolist',//el表示element,用于挂载要管理的元素
data:{//data用于保存数据
list:['写代码','吃饭饭','睡觉觉'],
content:"好好学习,天天向上"
},
methods:{
add:function(){
this.list.push(this.content)
},
remove:function(index){
this.list.splice(index,1);//(下标,删除个数)
},
removeall:function(){
this.list = []
}
}
})
</script>

10.网络应用(axios)

网络请求库:axios

1
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

(1)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
<div>
<button class="get">get请求</button>
<button class="post">post请求</button>
<!-- <input type="button" value="get" class="get"> -->
</div>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/javascript">
document.querySelector(".get").onclick = function(){
// 通过js获取class为get的按钮点击事件
axios.get("https://autumnfish.cn/api/joke/list?num=3")
.then(function(response){
console.log(response);
})
}
document.querySelector(".post").onclick = function(){
axios.post("https://autumnfish.cn/api/user/reg",
{username:"jack"})
.then(function(response){
console.log(response);
},function(err){
console.log(err);
})
}
</script>

(2)axios+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
25
26
<div id="app">
<button class="get" @click="getrequest">get请求</button>
<button class="post">post请求</button>
<p>{{joke}}</p>
<!-- <input type="button" value="get" class="get"> -->
</div>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/javascript">
var app = new Vue({
el : "#app",
data : {
joke : ""
},
methods:{
getrequest:function(){
// axios回调函数的this会改变,因此使用that进行保存
var that = this
axios.get("https://autumnfish.cn/api/joke").then
(function(response){
console.log(response);
that.joke = response.data;
})
}
}
})
</script>

11.实践—天知道

(1)weather.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div id="app">
<input type="text" @keyup.enter="lookup" v-model="addition" autofocus="autofocus">
<button @click="lookup">搜索</button>
<p>
热点城市:
<span @click="changecity('北京')">北京</span>
<span @click="changecity('深圳')">深圳</span>
<span @click="changecity('成都')">成都</span>
</p>
<div v-if="info.length>0">
{{addition}}
<ul v-for="item in info">
<li>
日期:{{item.date}}
温度:{{item.low}}/{{item.high}}
风向:{{item.fengxiang}}
</li>
</ul>
</div>
</div>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="weather.js"></script>

(2)weather.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var app = new Vue({
el : "#app",
data : {
addition : "",
info: ""
},
methods:{
lookup:function(){
var that = this
axios.get("https://wthrcdn.etouch.cn/weather_mini?city="+that.addition).then
(function(response){
console.log(response.data);
console.log(response.data.data);
that.info = response.data.data.forecast
})
},
changecity:function(city){
this.addition = city;
this.lookup();
}
}
})

12.实践—音乐播放器

功能:1歌曲搜索;2歌曲播放;3歌曲封面;4歌曲评论;5播放动画;6mv播放

(1)music.html

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="player">
<input type="text" @keyup.enter="searchmusic" v-model="query" autofocus="autofocus">
<button @click="searchmusic">搜索</button>
<p><audio ref="audio" @play="play" @pause="pause" :src="musicurl" controls autoplay loop style="width: 50%;"></audio></p>
<ul v-for="(item,index) in musiclist">
<li>
{{index+1}}:{{item.name}}
<button @click="playmusic(item.id)">播放</button>
<button v-if="item.mvid!=0" @click="playmv(item.mvid)">MV</button>
</li>
</ul>
<img :src="musicpic">
<div>
<ul v-for="comment in hotComments">
<li>
<img :src="comment.user.avatarUrl" width="10%">{{comment.user.nickname}}:
{{comment.content}}
</li>
</ul>
</div>
<video :src="mvurl" controls="controls" v-show="ifshow"></video>
</div>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="music.js"></script>

(2)music.js

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
var app = new Vue({
el : "#player",
data : {
query:"",
musiclist:[],
musicurl:"",
musicpic:"",
hotComments:[],
mvurl:"",
ifshow:false,

},
methods:{
searchmusic:function(){
var that = this;
axios.get("https://autumnfish.cn/search?keywords="+this.query)
.then(function(response){
that.musiclist = response.data.result.songs;
},
function(err){
console.log(err)
})
},
playmusic:function(musicid){
var that = this;
// 播放音乐
axios.get("https://autumnfish.cn/song/url?id="+musicid)
.then(function(response){
that.musicurl = response.data.data[0].url;
},
function(err){
console.log(err)
})
// 音乐图片
axios.get("https://autumnfish.cn/song/detail?ids="+musicid)
.then(function(response){
that.musicpic = response.data.songs[0].al.picUrl;
},
function(err){
console.log(err)
})

// 音乐评论
axios.get("https://autumnfish.cn/comment/hot?type=0&id="+musicid)
.then(function(response){
that.hotComments = response.data.hotComments;
console.log(response.data.hotComments)
},
function(err){
console.log(err)
})
},
play:function(){
console.log("play");
},
pause:function(){
console.log("pause");
},
playmv:function(mvid){
var that = this;
axios.get("https://autumnfish.cn/mv/url?id="+mvid)
.then(function(response){
that.ifshow = true;
that.mvurl = response.data.data.url;
},
function(err){
console.log(err)
})
}
}
})