# Vue2教程 - 11 自定义指令
在前面我们使用了很多的 Vue 的内置指令来完成功能,例如 v-bind
、v-show
、v-text
。
我们也可以自定义指令来完成想要的功能,如果想要实现自定义指令,就要对 DOM 进行操作,其实内置指令也是这么做的。
下面通过一个简单的功能来熟悉一下自定义指令。
实现这样一个功能:
v-text
指令是将内容显示在标签中,我们编写一个功能,在内容前面加上 逗比
。
# 11.1 全局指令
使用 Vue.directive
来定义全局指令,第一个参数是指令的名称,第二个参数是一个对象,对象中定义了一些回调方法,常用的有bind
、inserted
、update
、componentUpdated
、unbind
。
inserted
函数会在 dom 元素被插入到页面中的时候回调;bind
的函数是在元素加载到内存中就会回调,所以bind
函数在inserted
函数之前执行。- 回调函数的第一个参数都是绑定指令的那个元素。
具体实现:
<!-- 结构 -->
<template>
<div id="demo">
<div v-text="count"></div>
<!-- 2.使用指令 -->
<div v-doubi="msg"></div>
<button @click="changeData">改变data</button>
</div>
</template>
<!-- 脚本 -->
<script>
import Vue from 'vue'
// 1.定义全局指令
Vue.directive('doubi', {
// 在每个函数中,第一个参数都是element,表示被绑定了指令的那个DOM元素,这个element参数,是一个原生的JS对象
// 每当指令绑定到元素上的时候,会立即执行这个bind 函数,只执行一次
bind: function (element, binding) {
// 此时元素刚绑定了指令,还没有插入到DOM中去
console.log('执行bind函数:', element, binding);
},
// inserted表示元素插入到DOM中的时候会执行inserted函数,只执行一次
inserted: function (element, binding) {
console.log('执行inserted函数:', element, binding);
element.innerText = "逗比: " + binding.value // 初始化,前面添加上逗比
},
// 当模板中有数据更新的时候,即使不是当前指令用到的数据,都会执行updated,可能会触发多次
update: function (element, binding) {
console.log('执行update函数:', element, binding.value);
element.innerText = "逗比: " + binding.value // 数据更新后,前面添加上逗比
}
});
export default {
name: 'App',
data() {
return {
msg: "Hello",
count: 0
}
},
methods: {
changeData: function() {
this.count++
}
},
}
</script>
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
Vue.directive()
有两个参数:
参数1:指令的名称,注意,在定义的时候,指令的名称前面,不需要加
v-
前缀,但是在调用的时候,必须在指令名称前加上v-
前缀来进行调用。参数2:是一个对象,这个对象身上有一些指令相关的回调函数,这些函数可以在特定的阶段执行相关的操作。
指令的回调函数有两个参数:
- 第一个参数:是指令所绑定的DOM元素,它是
HTMLElement
类型,通过这个参数,你可以直接访问和操作DOM。例如,你可以改变元素的样式、属性、或者监听事件等。 - 第二个参数:是一个对象,它包含了关于指令的详细信息,如指令的值、参数、修饰符等。
需要注意:当模板中有数据更新的时候,即使不是当前指令用到的数据,都会执行 updated
。
执行效果:
# 11.2 定义私有指令
私有指令只能在当前组件中使用。
定义私有指令和定义全局指令区别不大,就是在组件实例中定义。通过 directives
属性来设置;指定指令名称和回调钩子函数。
<!-- 结构 -->
<template>
<div id="demo">
<!-- 2.使用指令 -->
<div v-doubi="msg"></div>
</div>
</template>
<!-- 脚本 -->
<script>
export default {
name: 'App',
data() {
return {
msg: "Hello",
count: 0
}
},
// 1.自定义私有指令
directives: {
'doubi': {
bind: function (element, binding) {
console.log('执行bind函数:', element, binding.value);
},
inserted: function (element, binding) {
console.log('执行函数:', element, binding.value);
element.innerText = "逗比: " + binding.value // 初始化,前面添加上逗比
},
update: function (element, binding) {
console.log('执行update函数:', element, binding.value);
element.innerText = "逗比: " + binding.value // 数据更新后,前面添加上逗比
}
}
}
}
</script>
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
# 11.3 指令传递参数
在上面我们创建的自定义指令,传递的参数是 data 中的参数,如果需要,还可以通过如下形式传递参数都可以
# 1 不传递参数
如果不需要参数,还可以不传递参数。
<input type="text" v-doubi>
# 2 传递字符串参数
字符串参数需要使用''括起来,因为如果不括起来,会认为是vue中定义的属性;如果是数字就不需要添加单引号了。
<input type="text" v-doubi="'green'">
# 3 传递多个参数
如果想传递多个参数可以传递一个对象:
参数传递:
<input type="text" v-doubi="{'color1':'red', 'color2':'green'}">
参数获取:
binding.value.color1
需要注意,指令回调函数的参数,除了第一个参数 element
之外,其他参数都应该是只读的,切勿进行修改,如果需要在回调函数之间共享数据,建议通过元素的 dataset
来进行。
# 11.4 指令回调钩子函数的简写
在大多数情况下,我们可能想在 bind
和 update
钩子上做重复动作,并且不想关心其他的钩子函数,可以简写成如下:
// 自定义全局指令
Vue.directive('doubi', function(element, binding) {
element.innerText = "逗比: " + binding.value
});
// 自定义私有指令
var vm = new Vue({
el: '#app',
directives: {
// 注意:这个 function 等同于 把 代码写到了 bind 和 update 中去
'doubi': function (element, binding) {
element.innerText = "逗比: " + binding.value
}
}
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
简写的方式相当于在 bind
和 update
两个钩子方法中都写了相同的代码。
← 10-侦听器watch 12-生命周期函数 →