Skip to content
📈0️⃣

Vue3 自定义指令

什么是自定义指令?

在 Vue3 中, 自定义指令是一种扩展 Vue 的能力, 通过自定义指令我们可以在 DOM 元素上直接操作和操控 DOM; Vue3 对自定义指令进行了一些改进, 使得自定义指令的编写更加简洁和灵活;

一个自定义指令需要包含一些钩子函数, 用于处理不同的生命周期事件; 以下是 Vue3 中常用的自定义指令的钩子函数及其功能:

  • bind: 指令第一次绑定到元素时调用; 可以用来初始化一些数据、添加事件监听器等;
  • mounted: 元素被插入父组件时调用;
  • updated: 指令所在组件的 VNode 更新时调用, 但可能发生在其子 VNode 更新之前; 可以访问新旧的 VNode 信息;
  • unmounted: 指令与元素解绑时调用; 可以用来清理一些数据、移除事件监听器等;

组件内指令

首先,让我们看一下如何创建一个自定义插件,以全局指令为例:

vue
<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中使用。

全局指令

接下来,让我们看一下如何创建和使用全局指令:

js
// 定义一个全局指令,用于在元素上添加一个特定的类名
const app = Vue.createApp({});
app.directive("focus", {
  beforeMount(el) {
    el.focus();
  },
});
app.mount("#app");
vue
<input v-focus />

在这个例子中,我们定义了一个名为 focus 的全局指令。这个指令会在元素挂载时自动聚焦到该元素上。你可以在任何需要聚焦的元素上使用这个指令

案例一 v-highlight

下面是一个具体的例子, 展示如何在 Vue3 中编写一个自定义指令来实现点击元素时改变背景颜色的效果:

javascript
// 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");
html
<!-- 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; 该指令具有mountedupdated两个钩子函数, 在元素被插入并更新时分别会被调用; 在这两个钩子函数中, 我们利用binding参数来获取指令的值, 并将其应用到元素的背景颜色上;

➡️在演练场中尝试一下

在 App 组件中, 我们通过v-highlight指令来绑定元素, 并传入一个字符串'yellow'作为指令的值; 当元素被点击时, 我们可以调用changeColor方法来改变指令的值, 从而改变元素的背景颜色;

需要注意的是, 指令也可以接收修饰符, 修饰符是以点开头的特殊后缀, 用于指定额外的行为; Vue3 中的自定义指令支持多个修饰符的使用, 并且修饰符可以与指令的参数配合使用;

案例二 v-focus

例如, 我们可以编写一个自定义指令focus, 使得元素在渲染后自动获得焦点:

vue
<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 应用的行为;