什么是自定义指令?
当内置指令不能满足开发需求时,可以通过自定义指令来拓展额外的功能。自定义指令的主要作用是方便开发者通过直接操作DOM元素来实现业务逻辑。
Vue中的自定义指令分为两类,分别是私有自定义指令和全局自定义指令。
一个自定义指令由一个包含自定义指令生命周期函数的参数来定义。常用的自定义指令生命周期函数如下表所示。
函数名 | 说明 |
created() | 在绑定元素的属性前调用 |
beforeMount() | 在绑定元素被挂载前调用 |
mounted() | 在绑定元素的父组件及自身的所有子节点都挂载完成后调用 |
beforeUpdate() | 在绑定元素的父组件更新前调用 |
updated() | 在绑定元素的父组件及自身的所有子节点都更新后调用 |
beforeUnmount() | 在绑定元素的父组件卸载前调用 |
unmounted() | 在绑定元素的父组件卸载后调用 |
常用的自定义指令生命周期函数的参数如下表所示。
参数 | 说明 |
el | 指令所绑定的元素,可以直接用于操作DOM元素 |
binding | 一个对象,包含很多属性,用于接收属性的参数值 |
vnode | 代表绑定元素底层的虚拟节点 |
prevNode | 之前页面渲染中指令所绑定元素的虚拟节点 |
binding中包含以下6个常用属性。
value:传递给指令的值。
arg:传递给指令的参数。
oldValue:之前的值,仅在beforeUpdate()函数和updated()函数中可用,无论值是否更改都可用。
modifiers:一个包含修饰符的对象 (如果有)。例如,在v-my-directive.foo.bar 中,修饰符对象是{ foo: true, bar: true }。
instance:使用该指令的组件实例。
dir:指令的定义对象。
如果没有使用setup语法糖,可以在directives属性中声明私有自定义指令。例如,声明一个私有自定义指令color,示例代码如下。
export default {
directives: {
color: {}
}
}
在上述代码中,color为自定义指令的名称,指令名称可以自定义。名称为color的指令指向一个配置对象,对象中可以包含自定义指令的生命周期函数,可通过这些函数来操作DOM元素。
在使用自定义指令时,需要以“v-”开头,示例代码如下。
<h1 v-color>标题</h1>
如果使用setup语法糖,任何以“v”开头的驼峰式命名的变量都可以被用作一个自定义指令,示例代码如下。
<template>
<span v-color></span>
</template>
<script setup>
const vColor = { }
</script>
演示私有自定义指令的使用方法
创建src\components\DirectiveComponent.vue文件。
<template>
<p v-fontSize>DirectiveComponent组件</p>
</template>
<script setup>
const vFontSize = {}
</script>
修改DirectiveComponent组件,添加mounted()函数,实现元素挂载完成后文本字号的改变。
const vFontSize = {
mounted: el => {
el.style.fontSize = '24px'
}
}
全局自定义指令需要通过Vue应用实例的directive()方法进行声明,语法格式如下。
directive('自定义指令名称', 对象)
在上述语法格式中,directive()方法的第1个参数类型为字符串,表示全局自定义指令的名称;第2个参数类型为对象或者函数,可以是对象或者函数形式,用于接收指令的参数值。
演示全局自定义指令的使用方式
修改src\main.js文件,声明全局自定义指令fontSize。
import { createApp } from 'vue'
import './style.css'
import App from './components/DirectiveComponent.vue'
const app = createApp(App)
app.directive('fontSize', {
mounted: el => {
el.style.fontSize = '24px'
}
})
app.mount('#app')
在使用自定义指令时,开发人员可以通过自定义指令的参数改变元素的状态,传递的参数由自定义指令的生命周期函数的第2个参数接收。
在标签中使用自定义指令时,通过等号(=)的方式可以为当前指令绑定参数,示例代码如下。
<h1 v-color="color"></h1>
如果指令需要多个值,可以传递一个对象,示例代码如下。
<div v-demo="{ color: 'red', text: 'hello' }"></div>
演示自定义指令参数的使用方法
创建src\components\CustomDirective.vue文件。
<template>
<p v-fontSize="fontSize">DirectiveComponent组件</p>
<button @click=“fontSize = ‘24px’”>更改字号大小</button>
</template>
<script setup>
import { ref } from 'vue'
const fontSize = ref('12px')
const vFontSize = {
mounted: (el, binding) => { el.style.fontSize = binding.value },
}
</script>
在自定义指令fontSize中添加updated()函数,实现自定义指令绑定的参数改变时,页面进行同步更改。
const vFontSize = {
// 原有代码……
updated: (el, binding) => {
el.style.fontSize = binding.value
}
}
对于自定义指令来说,通常仅需要在mounted()函数和updated()函数中操作DOM元素,除此之外,不需要其他的生命周期函数。例如,4.3.4小节CustomDirective 组件中的mounted()函数和updated()函数中的代码完全相同。此时,可以将自定义指令简写为函数形式。
将私有自定义指令简写为函数形式的示例代码如下。
const vFontSize = (el, binding) => {
el.style.fontSize = binding.value
}
将全局自定义指令简写成函数形式的示例代码如下。
app.directive('fontSize', (el, binding) => {
el.style.fontSize = binding.value
})