vue2中如何自定义指令
在 Vue 2 中,自定义指令通过 Vue.directive()
方法或组件选项的 directives
对象定义
一、全局自定义指令
通过 Vue.directive()
全局注册,所有组件可用:
// main.js 或全局入口文件
import Vue from 'vue';// 注册全局指令 'my-directive'
Vue.directive('my-directive', {// 指令的生命周期钩子bind(el, binding, vnode) {console.log('指令首次绑定到元素时调用', el);},inserted(el, binding, vnode) {console.log('元素插入父节点时调用', el);},update(el, binding, vnode, oldVnode) {console.log('组件更新时调用(可能发生在子组件更新之前)', el);},componentUpdated(el, binding, vnode, oldVnode) {console.log('组件及子组件全部更新后调用', el);},unbind(el, binding, vnode) {console.log('指令与元素解绑时调用', el);}
});
使用方式:
<div v-my-directive="someValue"></div>
二、局部自定义指令
在组件选项中通过 directives
定义,仅当前组件可用:
export default {directives: {'my-directive': {bind(el, binding) {// 指令逻辑el.style.color = binding.value;}}},data() {return { color: 'red' };}
}
模板中使用:
<p v-my-directive="color">这段文字会变成红色</p>
三、指令钩子函数详解
每个指令可包含以下钩子(均为可选):
钩子名称 | 调用时机 | 参数说明 |
---|---|---|
bind | 指令第一次绑定到元素时调用(一次性初始化设置) | el : 指令绑定的元素binding : 包含指令信息的对象vnode : Vue 虚拟节点 |
inserted | 绑定元素插入父节点时调用(不保证已被渲染) | 同上 |
update | 所在组件更新时调用(可能发生在子组件更新前) | 新增 oldVnode 参数 |
componentUpdated | 所在组件及子组件全部更新后调用 | 同上 |
unbind | 指令与元素解绑时调用(清理工作) | 同 bind |
四、binding
对象属性
钩子函数的 binding
参数包含以下属性:
属性 | 说明 |
---|---|
name | 指令名(不含 v- 前缀) |
value | 指令绑定的值(如 v-my-dir="1 + 1" 的 value 为 2 ) |
oldValue | 指令绑定的前一个值(仅在 update 和 componentUpdated 中可用) |
expression | 字符串形式的绑定表达式(如 v-my-dir="1 + 1" 的 expression 为 "1 + 1" ) |
arg | 指令参数(如 v-my-dir:arg 的 arg 为 "arg" ) |
modifiers | 包含修饰符的对象(如 v-my-dir.mod1.mod2 的 modifiers 为 { mod1: true, mod2: true } ) |
五、实用示例
1. 自动聚焦输入框
Vue.directive('focus', {inserted(el) {el.focus();}
});
<input v-focus>
2. 权限控制指令
Vue.directive('permission', {inserted(el, binding) {if (!checkPermission(binding.value)) {el.parentNode.removeChild(el);}}
});
<button v-permission="'admin'">仅管理员可见</button>
3. 拖拽指令
Vue.directive('drag', {bind(el) {el.onmousedown = (e) => {const disX = e.clientX - el.offsetLeft;const disY = e.clientY - el.offsetTop;document.onmousemove = (e) => {el.style.left = e.clientX - disX + 'px';el.style.top = e.clientY - disY + 'px';};document.onmouseup = () => {document.onmousemove = null;};};}
});
<div v-drag style="position: absolute">拖拽我</div>
七、注意事项
-
避免滥用:优先使用组件和 props 解决需求,指令适合 DOM 操作相关功能。
-
样式处理:在
bind
或inserted
中修改样式,避免在update
中重复操作。 -
内存泄漏:在
unbind
中移除事件监听器和定时器。
通过自定义指令,你可以直接操作 DOM 并复用常见行为,从而增强 Vue 的灵活性。