Vue3 自定义指令
什么是自定义指令?
在 Vue3 中, 自定义指令是一种扩展 Vue 的能力, 通过自定义指令我们可以在 DOM 元素上直接操作和操控 DOM; Vue3 对自定义指令进行了一些改进, 使得自定义指令的编写更加简洁和灵活;
一个自定义指令需要包含一些钩子函数, 用于处理不同的生命周期事件; 以下是 Vue3 中常用的自定义指令的钩子函数及其功能:
bind
: 指令第一次绑定到元素时调用; 可以用来初始化一些数据、添加事件监听器等;mounted
: 元素被插入父组件时调用;updated
: 指令所在组件的 VNode 更新时调用, 但可能发生在其子 VNode 更新之前; 可以访问新旧的 VNode 信息;unmounted
: 指令与元素解绑时调用; 可以用来清理一些数据、移除事件监听器等;
组件内指令
首先,让我们看一下如何创建一个自定义插件,以全局指令为例:
<template>
<div v-custom-directive>Lorem ipsum dolor sit amet</div>
</template>
<script setup>
const vCustomDirective = {
mounted(el) {
el.style.color = "red";
},
};
</script>
在上面的代码中,指令会在绑定元素被插入到 DOM 中时调用,我们在这个钩子函数中将绑定元素的文字颜色设置为红色。
需要注意的是,在使用自定义指令时,需要以v-
为前缀使用该指令,<script setup>
模块内无需注册直接在 template
中使用。
全局指令
接下来,让我们看一下如何创建和使用全局指令:
// 定义一个全局指令,用于在元素上添加一个特定的类名
const app = Vue.createApp({});
app.directive("focus", {
beforeMount(el) {
el.focus();
},
});
app.mount("#app");
<input v-focus />
在这个例子中,我们定义了一个名为 focus 的全局指令。这个指令会在元素挂载时自动聚焦到该元素上。你可以在任何需要聚焦的元素上使用这个指令
案例一 v-highlight
下面是一个具体的例子, 展示如何在 Vue3 中编写一个自定义指令来实现点击元素时改变背景颜色的效果:
// main.js
import { createApp } from "vue";
import App from "./App.vue";
const app = createApp(App);
app.directive("highlight", {
mounted(el, binding) {
el.style.backgroundColor = binding.value;
},
updated(el, binding) {
el.style.backgroundColor = binding.value;
},
});
app.mount("#app");
<!-- App.vue -->
<template>
<div v-highlight="'yellow'" @click="changeColor">Click me!</div>
</template>
<script>
export default {
methods: {
changeColor() {
// do something
},
},
};
</script>
在上述代码中, 我们在主文件main.js
中通过app.directive
方法来注册一个全局的自定义指令highlight
; 该指令具有mounted
和updated
两个钩子函数, 在元素被插入并更新时分别会被调用; 在这两个钩子函数中, 我们利用binding
参数来获取指令的值, 并将其应用到元素的背景颜色上;
在 App 组件中, 我们通过v-highlight
指令来绑定元素, 并传入一个字符串'yellow'
作为指令的值; 当元素被点击时, 我们可以调用changeColor
方法来改变指令的值, 从而改变元素的背景颜色;
需要注意的是, 指令也可以接收修饰符, 修饰符是以点开头的特殊后缀, 用于指定额外的行为; Vue3 中的自定义指令支持多个修饰符的使用, 并且修饰符可以与指令的参数配合使用;
案例二 v-focus
例如, 我们可以编写一个自定义指令focus
, 使得元素在渲染后自动获得焦点:
<template>
<div>
<input v-focus.lazy />
</div>
</template>
<script setup>
const vFocus = {
mounted(el, binding) {
if (binding.modifiers.lazy) {
setTimeout(() => {
el.focus();
}, 0);
} else {
el.focus();
}
},
};
</script>
指令语法导图
在这里你可以直观地看到完整的指令语法:
总结一下, Vue3 的自定义指令通过注册全局或局部的方式来扩展 Vue 的功能; 通过自定义指令, 我们可以操作和操控 DOM 元素, 以实现一些自定义的行为; 在自定义指令中, 我们可以编写多个钩子函数来响应不同的生命周期事件, 并利用 binding 参数来获取指令的值和修饰符; 自定义指令的灵活性和可扩展性使得我们能够更好地定制和控制 Vue 应用的行为;