自定义指令 (directives)
# 自定义指令 (directives)
# 1. 什么是自定义指令
Vue 官方提供了 v-text
、v-for
、v-model
、v-if
等常用的指令。除此之外,Vue 还允许开发者自定义指令,以便实现更复杂的 DOM 操作。
# 2. 自定义指令的分类
自定义指令可以分为两类:
- 私有自定义指令:仅在当前组件内使用的自定义指令。
- 全局自定义指令:在整个应用程序中都可以使用的自定义指令。
# 3. 声明私有自定义指令
在每个 Vue 组件中,可以在 directives
节点下声明私有自定义指令。
export default {
// 私有自定义指令的声明
directives: {
// 定义一个名为 color 的自定义指令
color: {
// bind 钩子函数:指令第一次绑定到元素时调用
bind(el, binding) {
el.style.color = binding.value; // 设置元素的文字颜色
},
// update 钩子函数:组件的 VNode 更新时调用
update(el, binding) {
el.style.color = binding.value; // 更新元素的文字颜色
}
},
// 定义一个名为 font-size 的自定义指令
'font-size': {
// bind 钩子函数:指令第一次绑定到元素时调用
bind(el, binding) {
el.style.fontSize = binding.value; // 设置元素的字体大小
},
// update 钩子函数:组件的 VNode 更新时调用
update(el, binding) {
el.style.fontSize = binding.value; // 更新元素的字体大小
}
}
}
};
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
在这个示例中,定义了两个私有自定义指令 color
和 font-size
。注意到 font-size
需要加引号,因为它包含了特殊字符(-
)。
# 4. 使用自定义指令
在使用自定义指令时,需要加上 v-
前缀。
在模板中使用自定义指令
<template>
<div>
<!-- 使用自定义指令 v-color -->
<h1 v-color="'blue'">这是一段蓝色的文字</h1>
<!-- 使用自定义指令 v-font-size -->
<h2 v-font-size="'18px'">这是一段中等字体的文字</h2>
</div>
</template>
2
3
4
5
6
7
8
在这个示例中,使用了自定义指令 v-color
和 v-font-size
来设置文字的颜色和字体大小。
# 5. 为自定义指令动态绑定参数值
在模板结构中使用自定义指令时,可以通过等号(=
)的方式,为当前指令动态绑定参数值。
动态绑定参数值
<template>
<div>
<h1 v-color="dynamicColor">这是一段动态颜色的文字</h1>
<h2 v-font-size="dynamicFontSize">这是一段动态字体大小的文字</h2>
</div>
</template>
<script>
export default {
data() {
return {
dynamicColor: 'green', // 动态绑定的颜色值
dynamicFontSize: '24px' // 动态绑定的字体大小值
};
},
directives: {
// 定义一个名为 color 的自定义指令
color: {
bind(el, binding) {
el.style.color = binding.value; // 设置元素的文字颜色
},
update(el, binding) {
el.style.color = binding.value; // 更新元素的文字颜色
}
},
// 定义一个名为 font-size 的自定义指令
'font-size': {
bind(el, binding) {
el.style.fontSize = binding.value; // 设置元素的字体大小
},
update(el, binding) {
el.style.fontSize = 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
37
在这个示例中,v-color
和 v-font-size
指令的参数值是动态的,分别绑定了 dynamicColor
和 dynamicFontSize
数据属性。
# 6. 通过 binding
获取指令的参数值
在声明自定义指令时,可以通过形参中的第二个参数 binding
来接收指令的参数值。
使用 binding
获取参数值
<template>
<div>
<h1 v-color="dynamicColor">这是一段动态颜色的文字</h1>
</div>
</template>
<script>
export default {
data() {
return {
dynamicColor: 'green' // 动态绑定的颜色值
};
},
directives: {
// 定义一个名为 color 的自定义指令
color: {
bind(el, binding) {
console.log(binding.value); // 输出绑定的颜色值
el.style.color = binding.value; // 设置元素的文字颜色
},
update(el, binding) {
el.style.color = 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
在这个示例中,通过 binding.value
获取指令的参数值,并输出到控制台。
# el
参数的作用
el
:表示指令绑定的 DOM 元素,可以直接操作这个元素。该示例通过操作el
参数直接修改 DOM 元素的样式。
# binding
对象的其他属性
除了 value
,binding
对象还包含其他有用的属性:
name
:指令名,不包括v-
前缀。value
:指令的绑定值,例如v-color="dynamicColor"
中绑定的值dynamicColor
。oldValue
:指令绑定的前一个值,仅在update
和componentUpdated
钩子中可用。expression
:绑定值的字符串形式。arg
:传给指令的参数,例如v-my-directive:foo
中的foo
。modifiers
:一个包含修饰符的对象,例如v-my-directive.foo.bar
中的modifiers
对象是{ foo: true, bar: true }
。
示例代码
<template>
<div>
<h1 v-color:foo.bar="dynamicColor">这是一段动态颜色的文字</h1>
</div>
</template>
<script>
export default {
data() {
return {
dynamicColor: 'green' // 动态绑定的颜色值
};
},
directives: {
// 定义一个名为 color 的自定义指令
color: {
bind(el, binding) {
console.log('name:', binding.name); // 输出指令名
console.log('value:', binding.value); // 输出绑定的颜色值
console.log('oldValue:', binding.oldValue); // 输出前一个绑定值
console.log('expression:', binding.expression); // 输出绑定值的字符串形式
console.log('arg:', binding.arg); // 输出指令的参数
console.log('modifiers:', binding.modifiers); // 输出修饰符对象
el.style.color = binding.value; // 设置元素的文字颜色
},
update(el, binding) {
el.style.color = 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
在这个示例中,通过 binding
对象的属性获取更多关于指令的信息。
# 7. update
函数
bind
函数只调用一次,当指令第一次绑定到元素时调用。当 DOM 更新时,bind
函数不会被触发,而 update
函数会在每次 DOM 更新时被调用。
update
函数
<template>
<div>
<h1 v-color="dynamicColor">这是一段动态颜色的文字</h1>
<button @click="changeColor">改变颜色</button>
</div>
</template>
<script>
export default {
data() {
return {
dynamicColor: 'green' // 初始颜色
};
},
methods: {
changeColor() {
this.dynamicColor = this.dynamicColor === 'green' ? 'red' : 'green'; // 切换颜色
}
},
directives: {
// 定义一个名为 color 的自定义指令
color: {
bind(el, binding) {
el.style.color = binding.value; // 设置元素的文字颜色
},
update(el, binding) {
el.style.color = 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
在这个示例中,update
函数在每次 dynamicColor
更新时都会被调用,从而更新元素的颜色。DOM 更新是指数据变化引起的视图更新,例如这里的 dynamicColor
的变化。
# 8. 函数简写
如果 bind
和 update
函数中的逻辑完全相同,则对象格式的自定义指令可以简写成函数格式。
函数简写
<template>
<div>
<h1 v-color="dynamicColor">这是一段动态颜色的文字</h1>
<button @click="changeColor">改变颜色</button>
</div>
</template>
<script>
export default {
data() {
return {
dynamicColor: 'green' // 初始颜色
};
},
methods: {
changeColor() {
this.dynamicColor = this.dynamicColor === 'green' ? 'red' : 'green'; // 切换颜色
}
},
directives: {
// 定义一个名为 color 的自定义指令,简写形式
color(el, binding) {
el.style.color = 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
在这个示例中,使用了函数简写形式定义 color
自定义指令。
# 9. 全局自定义指令
全局共享的自定义指令需要在 main.js
中通过 Vue.directive()
进行声明。
# 在 main.js
中定义全局自定义指令
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
Vue.config.productionTip = false;
// 定义全局自定义指令 'v-color'
Vue.directive('color', {
bind(el, binding) {
el.style.color = binding.value; // 设置元素的颜色
},
update(el, binding) {
el.style.color = binding.value; // 更新元素的颜色
}
});
new Vue({
router,
store,
render: h => h(App),
}).$mount('#app');
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 使用全局自定义指令
在使用全局自定义指令时,组件内无需再次声明指令,直接使用即可:
<template>
<div>
<h1 v-color="dynamicColor">这是一段动态颜色的文字</h1>
<button @click="changeColor">改变颜色</button>
</div>
</template>
<script>
export default {
data() {
return {
dynamicColor: 'green' // 初始颜色
};
},
methods: {
changeColor() {
this.dynamicColor = this.dynamicColor === 'green' ? 'red' : 'green'; // 切换颜色
}
}
};
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
在 main.js
文件中,通过 Vue.directive
定义了一个全局自定义指令 v-color
,在组件中可以直接使用这个指令来动态设置文字的颜色。