Vue 3 自定义指令简解

412 阅读3分钟

什么是Vue 3自定义指令?

除了 Vue 内置的一系列指令 (比如 v-model 或 v-show) 之外,Vue 还允许你注册自定义的指令 (Custom Directives)。

Vue 3自定义指令允许你直接操作DOM元素。它们可以用来添加特定的行为,例如自动聚焦、滚动处理、拖放等。在Vue 3中,自定义指令通过 directive 函数来定义,这一函数提供了更多的选项和灵活性。

在 vue 官网已有详细介绍。

如何创建一个简单的自定义指令?

一个自定义指令由一个包含类似组件生命周期钩子的对象来定义。钩子函数会接收到指令所绑定元素作为其参数。下面是一个自定义指令的例子,当一个 input 元素被 Vue 插入到 DOM 中后,它会被自动聚焦:

创建自定义指令

// directive.ts

import type { Directive } from 'vue'

export const focus: Directive = {
  mounted(el: HTMLElement) {
    el.focus();
  }
}

注册自定义指令

// main.ts

import { createApp } from 'vue'
import { focusDirective } from './directive.ts'
import App from './App.vue'

const app = createApp(App)

app.directive('focus', focusDirective);

app.mount('#app');

使用 v-focus

<template> 
  <input v-focus /> 
</template>

效果

刷新页面自动聚焦

20240630143935_rec_.gif

指令钩子

钩子函数

一个指令的定义对象可以提供几种钩子函数 (都是可选的):

import type { Directive, DirectiveBinding, VNode } from 'vue';

const myDirective: Directive = {
  // 在绑定元素的 attribute 前或事件监听器应用前调用
  created(el: HTMLElement, binding: DirectiveBinding, vnode: VNode, prevVnode: VNode | null){},
  // 在元素被插入到 DOM 前调用
  beforeMount(el, binding, vnode, prevVnode) {},
  // 在绑定元素的父组件
  // 及他自己的所有子节点都挂载完成后调用
  mounted(el, binding, vnode, prevVnode) {},
  // 绑定元素的父组件更新前调用
  beforeUpdate(el, binding, vnode, prevVnode) {},
  // 在绑定元素的父组件及他自己的所有子节点都更新后调用
  updated(el, binding, vnode, prevVnode) {},
  // 绑定元素的父组件卸载前调用
  beforeUnmount(el, binding, vnode, prevVnode) {},
  // 绑定元素的父组件卸载后调用
  unmounted(el, binding, vnode, prevVnode) {}
}

钩子参数

在Vue 3中,自定义指令的钩子函数会接收以下几种参数,帮助你更精确地控制DOM操作和指令行为。

el
  • 描述: 指令绑定到的元素。这可以用于直接操作 DOM。
  • 类型: HTMLElement
  • 用途: 例如,设置元素的聚焦、修改元素样式等。
binding
  • 描述: 一个包含指令相关信息的对象,提供了多个有用的属性。
  • 类型: DirectiveBinding
  • 属性:
    • value: 传递给指令的值。例如在 v-my-directive="1 + 1" 中,值是 2
    • oldValue: 之前的值,仅在 beforeUpdateupdated 钩子中可用。无论值是否更改,它都可用。
    • arg: 传递给指令的参数(如果有的话)。例如在 v-my-directive:foo 中,参数是 "foo"
    • modifiers: 一个包含修饰符的对象(如果有的话)。例如在 v-my-directive.foo.bar 中,修饰符对象是 { foo: true, bar: true }
    • instance: 使用该指令的组件实例。
    • dir: 指令的定义对象。
vnode
  • 描述: 代表绑定元素的底层虚拟节点(VNode)。
  • 类型: VNode
  • 用途: 通过VNode可以访问更多上下文信息,例如组件实例等。
prevVnode
  • 描述: 代表之前的渲染中指令所绑定元素的虚拟节点(VNode)。
  • 类型: VNode | null
  • 用途: 仅在 beforeUpdateupdated 钩子中可用,用于比较新旧节点的不同。

应用场景(持续更新)

demo地址:github.com/baozjj/vue-…

  • Vue 3 自定义指令 - 添加loading效果
  • Vue 3 自定义指令 - 自动聚焦输入框
  • Vue 3 自定义指令 - 懒加载图片
  • Vue 3 自定义指令 - 拖拽功能
  • Vue 3 自定义指令 - 权限控制
  • Vue 3 自定义指令 - 点击外部关闭
  • Vue 3 自定义指令 - 复制到剪贴板
  • Vue 3 自定义指令 - 防抖按钮
  • Vue 3 自定义指令 - 滚动事件
  • Vue 3 自定义指令 - 元素粘性定位