什么是Vue 3自定义指令?
除了 Vue 内置的一系列指令 (比如 v-model 或 v-show) 之外,Vue 还允许你注册自定义的指令 (Custom Directives)。
Vue 3自定义指令允许你直接操作DOM元素。它们可以用来添加特定的行为,例如自动聚焦、滚动处理、拖放等。在Vue 3中,自定义指令通过 directive 函数来定义,这一函数提供了更多的选项和灵活性。
如何创建一个简单的自定义指令?
一个自定义指令由一个包含类似组件生命周期钩子的对象来定义。钩子函数会接收到指令所绑定元素作为其参数。下面是一个自定义指令的例子,当一个 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>
效果
刷新页面自动聚焦
指令钩子
钩子函数
一个指令的定义对象可以提供几种钩子函数 (都是可选的):
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: 之前的值,仅在beforeUpdate和updated钩子中可用。无论值是否更改,它都可用。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 - 用途: 仅在
beforeUpdate和updated钩子中可用,用于比较新旧节点的不同。
应用场景(持续更新)
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 自定义指令 - 元素粘性定位