数据绑定

Vue在设计上使用MVVM模式,当View发生变化时会自动更新到ViewModel,反之亦然。ViewViewModel之间通过双向绑定建立联系。

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
<template>
<div id="app">
<!-- 使用自定义过滤器对数据进行过滤 -->
<h1>{{date_time | formatDateTime}}</h1>
<h2>{{name}}</h2>
<input type="text" v-model="name" placeholder="你的名字">
<!-- 使用 v-pre 即可跳过这个元素和它的子元素的编译过程 -->
<h3 v-pre>{{这里的内容是不会被编译的}}</h3>
<!-- 除了简单的绑定属性值外,还可以使用 JavaScript 表达式进行简单的运算、三元运算 -->
<h3>{{isDone?"Done":"Not Done"}}</h3>
</div>
</template>

<script>
export default {
name: "app",
data: function() {
return {
name: "Hello esp-desk",
isDone: true,
date_time: new Date()
};
},
filters: {
formatDateTime: function(value) {
var date = new Date(value);
var year = date.getFullYear();
var month = date.getMonth() + 1;
var day = date.getDate();
var hours = date.getHours();
var minutes = date.getMinutes();
var seconds = date.getSeconds();
return (
year +
"-" +
month +
"-" +
day +
" " +
hours +
":" +
minutes +
":" +
seconds
);
}
},
created: function() {
// 实例创建完成后调用,此阶段完成了数据的观测等,但尚未挂载, 此时 $el 还不可用。需要初始化处理一些数据时会比较有用
console.log(this.name);
},
mounted: function() {
//el 挂载到实例上后调用,一般第一个业务逻辑会在这里开始
console.log(this.$el);
var _this = this; //声明一个变量指向 Vue 实例 this ,保证作用域一致
this.timer = setInterval(() => {
_this.date_time = new Date();
}, 1000);
},
beforeDestroy: function() {
//实例销毁之前调用。主要解绑一些使用 addEventListener 监听的事件等
console.log("beforeDestory");
if (this.timer) {
clearInterval(this.timer);
}
}
};
</script>

<style lang="scss">
</style>

计算属性

模板内的表达式只能用于简单的运算,逻辑复杂时,使用vue实例的计算属性computed。计算属性可以完成各种复杂的逻辑,包括运算、函数调用等。计算属性还可以依赖多个vue实例的数据,只要其中任一数据有变化,计算属性就会重新执行。

计算属性与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
<template>
<div id="app">
<h2>{{reverseText}}</h2>
</div>
</template>

<script>
export default {
name: "app",
data() {
return {
text: "192.168.10.11"
};
},
computed: {
reverseText: function() {
return this.text
.split(".")
.reverse()
.join(".");
}
}
};
</script>

<style>
</style>

Vue指令

v-bind及其语法糖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<template>
<div id="app">
<img :src="imgUrl">
<a v-bind:href="url">百度</a>
</div>
</template>

<script>
export default {
name: "app",
data: function() {
return {
url: "https://www.baidu.com",
imgUrl: "https://s2.ax1x.com/2019/01/06/FHVUR1.jpg"
};
}
};
</script>

<style lang="scss">
</style>

绑定class

v-bind:class设置一个对象,可以动态切换class

1
2
3
<div id="app">
<div class="static" :class="{'active':isActive, 'error':isError}"></div>
</div>
  • 类名active依赖于数据isActive,当其为true时,div会拥有类名Active,为false时则没有
  • :class可以与普通class共存
  • :class的表达式过长或者逻辑复杂时,还可以绑定计算属性

v-bind:class设置一个数组,应用一个class列表

1
2
3
4
5
6
7
8
9
10
11
12
<div id="app">
<div :class="[{'active': isActive}, errorCls]"></div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
isActive: true,
errorCls: 'error'
}
})
</script>

绑定style

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div id="app">
<div :style="styles">文本</div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
styles: {
color: 'red',
fontSize: 14 + 'px'
}
}
})
</script>

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
26
<template>
<div id="app">
<h2 v-if="show">这是一段文字</h2>
<button v-on:click="hideLabel">隐藏文字</button>
<button @click="showLabel">显示文字</button>
</div>
</template>

<script>
export default {
name: "app",
data: function() {
return {
show: true
};
},
methods: {
hideLabel: function() {
this.show = false;
},
showLabel: function() {
this.show = true;
}
}
};
</script>

v-once

v-once是一个不需要表达式的指令,作用是定义它的元素或组件只渲染一次,包括元素或组件的所有子节点。首次渲染后,不再随数据的变化重新渲染,将被视为静态内容。v-once在业务中很少使用,当需要进一步优化性能的时候,可能会用到。

v-if、v-else-if、v-else条件渲染指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<template>
<div id="app">
<template v-if="status===1">
<h2>status:1</h2>
</template>
<template v-else-if="status===2">
<h3>status:2</h3>
</template>
<template v-else>
<h4>status:3</h4>
</template>
</div>
</template>

<script>
export default {
name: "app",
data() {
return {
status: 3
};
}
};
</script>
  • Vue在渲染元素时,处于效率考虑,会尽可能复用已有的元素而非重新渲染。如果不希望这样做,可以使用Vue提供的key属性,它可以让你自己决定是否要复用元素,key的值必须是唯一的
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
<template>
<div id="app">
<template v-if="type==='name'">
<label>用户名:</label>
<input placeholder="输入用户名" :key="name-input">
</template>
<template v-else>
<label>邮箱:</label>
<input placeholder="输入邮箱" :key="mail-input">
</template>
<button @click="changeType">切换输入类型</button>
</div>
</template>

<script>
export default {
name: "app",
data() {
return {
type: "name"
};
},
methods: {
changeType: function() {
this.type = this.type === "name" ? "email" : "name";
}
}
};
</script>

v-show

v-show的用法与v-if基本一致,只不过v-show是改变元素的CSS属性display,当v-show表达式的值为false时,元素会隐藏,查看DOM结构会看到元素上加载了内联样式display:none

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
<div id="app">
<p v-show="status===1">当status为1时显示该行</p>
</div>
</template>

<script>
export default {
name: "app",
data() {
return {
status: 1
};
}
};
</script>
  • v-show只是简单的CSS属性切换,无论条件真与否,都会被编译,相比之下,v-if更适合条件不经常改变的场景,因为它切换开销相对较大,而v-show适用于频繁切换条件
  • v-show不能在\<template>上使用

列表渲染指令 v-for

遍历数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
<div id="app">
<ul>
<template v-for="(language,index) in languages">
<h2 :key="index">{{index}}</h2>
<li :key="index">{{language.name}}</li>
<li :key="index">{{language.IDE}}</li>
</template>
</ul>
</div>
</template>

<script>
export default {
name: "app",
data() {
return {
languages: [{ name: "C", IDE: "CLion" }, { name: "Java", IDE: "Eclipse" }]
};
}
};
</script>

枚举对象的属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
<div id="app">
<ul>
<li v-for="(value,key,index) in user" :key="index">{{index+1}}-{{key}}:{{value}}</li>
</ul>
</div>
</template>

<script>
export default {
name: "app",
data() {
return {
user: {
name: "morris",
age: 20,
gender: "male"
}
};
}
};
</script>

迭代整数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
<div id="app">
<span v-for="n in num" :key="n">{{n}} </span>
</div>
</template>

<script>
export default {
name: "app",
data() {
return {
num: 11
};
}
};
</script>