Vue指令

Vue中的指令按照不同用途分为下列6种:

  • 内容渲染指令
  • 属性绑定指令
  • 事件绑定指令
  • 双向绑定指令
  • 条件渲染指令
  • 列表渲染指令

内容渲染指令

内容渲染指令用于渲染DOM元素的文本内容,常用指令有如下3个:

  1. v-text
  2. { { } }
  3. v-html

v-text

v-text会将变量的值覆盖标签内的文本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<body>
<div id='app'>
<p v-text="username">我会被username变量的值覆盖</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
username: 'zs'
}
})
</script>

</body>

{ { } }

Vue提供的语法{ { } }称为插值表达式,专门用来解决v-text会覆盖文本的问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<body>
<div id='app'>
<p>姓名:{{ username }}</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
username: 'zs'
}
})
</script>

</body>

v-html

v-text 和 { { } } 只能渲染纯文本内容,如果想要把包含HTML标签的字符串渲染为页面的HTML元素,可以使用v-html指令。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<body>
<div id='app'>
<p v-html="discription"></p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
username: 'zs',
discription: '<h1> Test </h1>'
}
})
</script>

</body>

属性绑定指令

如果需要为元素的属性动态绑定属性值,需要用到v-bind属性绑定指令。

除了支持绑定简单的数据值,还支持绑定简单的JavaScript表达式运算。

语法:

1
2
v-bind:属性名 = "xxx"
:属性名 = "xxx"

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<body>
<div id='app'>
<input type="text" v-bind:placeholder="inputValue">
<input type="text" :placeholder="inputValue">
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
inputValue: '请输入内容'
}
})
</script>

</body>

事件绑定指令

vue提供了v-on事件绑定指令,用来辅助程序员为DOM元素绑定事件监听。

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
<body>
<div id='app'>
<h3> count的值为: {{ count }} </h3>
<!-- 语法格式:v-on:事件名称="事件处理函数名称" -->
<!-- 简写格式:@:事件名称="事件处理函数名称" -->
<button v-on:click="addCount"> +1 </button>
<button @click="addCount"> +1 </button>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
count: 0
},
//通过v-on绑定的事件处理函数,需要在methods节点中进行声明。
methods: {
addCount() {
this.count += 1
}
}
})
</script>
</body>

事件

原生DOM对象有onclick、oninput、onkeyup等原生事件,替换为Vue事件后,分别为:v-on:click、v-on:input、v-on:keyup。

事件参数对象

在原生DOM事件绑定中,可以在事件处理函数的形参处,接收参数对象event。

同理,在v-on指令(简写@)所绑定的事件中,同样可以接收到参数对象event。

示例代码:

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'>
<h3> count的值为: {{ count }} </h3>
<!-- 语法格式:v-on:事件名称="事件处理函数名称" -->
<button v-on:click="addCount"> +1 </button>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
count: 0
},
methods: {
addCount(e) { //接收事件参数对象event,简写为e。
const nowBgColor = e.target.style.backgroundColor
e.target.style.backgroundColor = nowBgColor === 'red' ? '' : 'red'
this.count += 1
}
}
})
</script>
</body>

绑定事件并传参

在使用v-on指令时,可以使用()进行传参,示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<body>
<div id='app'>
<h3> count的值为: {{ count }} </h3>
<!-- 语法格式:v-on:事件名称="事件处理函数名称" -->
<button v-on:click="addCount(2)"> +1 </button>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
count: 0
},
methods: {
addCount(step) {
this.count += step
}
}
})
</script>
</body>

$event

$event是vue提供的特殊变量,用来表示原生事件参数对象event。

示例代码:

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
<body>
<div id='app'>
<h3> count的值为: {{ count }} </h3>
<!-- 语法格式:v-on:事件名称="事件处理函数名称" -->
<button v-on:click="addCount(2, $event)"> +1 </button>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
count: 0
},
methods: {
addCount(step, e) {
const nowBgColor = e.target.style.backgroundColor
e.target.style.backgroundColor = nowBgColor === 'red' ? '' : 'red'
this.count += step
}
}
})
</script>
</body>

事件修饰符

在事件处理函数中调用 event.preventDefault() 或 event.stopPropagation() 是非常常见的需求。

因此,vue提供了事件修饰符的概念。常用的如下:

  • .prevent:阻止默认行为(如:阻止a链接跳转、阻止表单的提交)
  • .stop:阻止事件冒泡
  • .capture:以捕获模式触发当前事件的处理函数
  • .once:绑定的事件只触发一次
  • .self:只有在event.target是当前元素自身时触发事件处理函数

代码示例:

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'>
<h3> count的值为: {{ count }} </h3>
<!-- 语法格式:v-on:事件名称="事件处理函数名称" -->
<button v-on:click="addCount.prevent"> +1 </button>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
count: 0
},
methods: {
addCount(e) { //接收事件参数对象event,简写为e。
const nowBgColor = e.target.style.backgroundColor
e.target.style.backgroundColor = nowBgColor === 'red' ? '' : 'red'
this.count += 1
}
}
})
</script>
</body>

按键修饰符

在监听键盘事件时,我们经常需要判断详细的按键。此时,可以为键盘相关的事件添加按键修饰符。

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<body>
<div id='app'>
<!-- 只有在 'key' 是 'Enter' 时调用 'vm.addCount()' -->
<input @keyup.enter="submit"></input>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
count: 0
},
methods: {
submit() {
console.log('test')
}
}
})
</script>
</body>

双向绑定指令

vue提供了v-model双向数据绑定指令,用来辅助开发者在不操作DOM的前提下,快速获取表单的数据。

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'>
<p>用户名是:{{ username }}</p>
<input type="text" v-model="username">

<p>选中的省份是:{{ province }}</p>
<select v-model="province">
<option value="">请选择</option>
<option value="1">绿藤市</option>
<option value="2">山东省</option>
</select>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
username: '',
province: ''
}
})
</script>
</body>

修饰符

为了方便对用户输入的内容进行处理,vue为v-model指令提供了3个修饰符:

  • .number:自动将用户输入值转为数值类型
  • .trim:自动过滤用户输入的首尾空白字符
  • .lazy:在“change”时而非“input”时更新

条件渲染指令

条件渲染指令按需控制DOM的显示和隐藏,有如下两个:

  • v-if
  • v-show
1
2
3
4
<div id='app'> 
<p v-if="networkState === 200">请求成功 ---被v-if控制</p>
<p v-show="networkState === 200">请求成功 ---被v-show控制</p>
</div>

区别

  • v-if指令会动态的创建或移除DOM元素
  • v-show指令会动态的为元素添加style=”display: none;”样式

二者性能消耗不同,v-if需要更高的切换开销,而v-show有更高的初始渲染开销。

如果需要频繁切换,使用v-show,否则使用v-if。

v-else

v-if可以单独使用,也可以配合v-else进行使用。

v-else-if同理,不再具体演示。

代码示例:

1
2
3
4
<div id='app'> 
<p v-if="Math.random() > 0.5">随机数大于0.5</p>
<p v-else>随机数小于等于0.5</p>
</div>

列表渲染指令

vue提供了v-for列表渲染指令,用于基于一个数组来循环渲染一个列表结构。

v-for指令需要使用item in items形式的特殊语法,其中:

  • items是待循环的数组
  • item是被循环的每一项

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<body>
<div id='app'>
<ul>
<li v-for="item in list"> 姓名是: {{ item.name }} </li>
</ul>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
list: [
{ id: 1 , name: 'zs' },
{ id: 2 , name: 'ls' },
]
}
})
</script>
</body>

索引

v-for指令还支持可选的第二个参数,即当前项的索引。

语法格式:(item, index) in items

代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<body>
<div id='app'>
<ul>
<li v-for="(item, index) in list"> 索引是:{{ index }} 姓名是: {{ item.name }} </li>
</ul>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
list: [
{ id: 1 , name: 'zs' },
{ id: 2 , name: 'ls' },
]
}
})
</script>
</body>

key

当列表数据变化时,默认情况下,Vue会尽可能复用已存在的DOM元素,从而提升渲染性能。

但这种默认的性能优化策略,会导致有状态的列表无法被更新。

因此,我们需要为每项提供一个唯一的key属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<body>
<div id='app'>
<ul>
<!-- 加key属性的好处: -->
<!-- 1.正确维护列表的状态 -->
<!-- 2.复用现有的DOM元素,提高渲染性能 -->
<li v-for="(item, index) in list" :key="id"> 索引是:{{ index }} 姓名是: {{ item.name }} </li>
</ul>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data: {
list: [
{ id: 1 , name: 'zs' },
{ id: 2 , name: 'ls' },
]
}
})
</script>
</body>

Key的注意事项:

  1. Key的值只能是数字或字符串。
  2. key的值必须具有唯一性。
  3. 建议把数据项的id作为key。
  4. 使用index的值当作key无意义,index不唯一。
  5. 建议使用v-for指令时一定要指定key。