指令钩子函数
自定义指令通过钩子函数在元素生命周期不同阶段执行逻辑,掌握各钩子的触发时机是使用指令的关键。
钩子函数一览
Vue 指令提供 5 个可选钩子函数:
| 钩子 | 触发时机 | 常用度 |
|---|---|---|
bind | 指令第一次绑定到元素时调用 | 高 |
inserted | 被绑定元素插入父节点时调用 | 高 |
update | 组件 VNode 更新时调用 | 中 |
componentUpdated | 组件 VNode 及子 VNode 全部更新后调用 | 中 |
unbind | 指令与元素解绑时调用 | 低 |
各钩子详解
bind
指令首次绑定到元素时触发,仅执行一次。适合执行一次性的初始化设置。
JavaScript
Vue.directive('demo', {
bind(el, binding) {
console.log('bind 触发', binding.value)
el.dataset.init = 'true'
}
})
bind阶段元素尚未插入父节点,此时无法获取元素尺寸或聚焦。
inserted
元素插入父节点时触发。适用于需要访问父节点或执行 DOM 相关操作的场景。
JavaScript
Vue.directive('scroll-top', {
inserted(el) {
el.scrollTop = 0
}
})
update
组件 VNode 更新时触发,可能在子组件更新之前发生。用于响应数据变化。
JavaScript
Vue.directive('highlight', {
update(el, binding) {
if (binding.value !== binding.oldValue) {
el.classList.add('highlight')
setTimeout(() => el.classList.remove('highlight'), 500)
}
}
})
componentUpdated
组件及子组件全部更新完成后触发。适用于依赖更新后 DOM 状态的场景。
JavaScript
Vue.directive('log-update', {
componentUpdated(el, binding, vnode) {
console.log('更新完成后的 DOM 内容:', el.innerHTML)
}
})
unbind
指令与元素解绑时触发,仅执行一次。适合执行清理工作。
JavaScript
Vue.directive('click-outside', {
bind(el, binding) {
el._clickOutsideHandler = (e) => {
if (!el.contains(e.target)) {
binding.value()
}
}
document.addEventListener('click', el._clickOutsideHandler)
},
unbind(el) {
document.removeEventListener('click', el._clickOutsideHandler)
}
})
使用
bind添加的事件监听器必须在unbind中移除,否则会造成内存泄漏。
钩子参数
每个钩子函数接收以下参数:
| 参数 | 说明 |
|---|---|
el | 指令绑定的 DOM 元素,可直接操作 |
binding | 对象,包含 name、value、oldValue、expression、arg、modifiers |
vnode | Vue 编译生成的虚拟节点 |
oldVnode | 上一个虚拟节点(仅 update 和 componentUpdated 可用) |
JavaScript
Vue.directive('info', {
bind(el, binding, vnode) {
console.log('指令名:', binding.name) // info
console.log('绑定值:', binding.value) // 传入的值
console.log('表达式:', binding.expression) // 原始表达式字符串
console.log('参数:', binding.arg) // v-info:arg 中的 arg
console.log('修饰符:', binding.modifiers) // v-info.foo.bar 中的 { foo: true, bar: true }
}
})
要点总结
- 5 个钩子按元素生命周期依次触发:bind -> inserted -> update -> componentUpdated -> unbind
bind和inserted最常用,区别在于元素是否已插入父节点update和componentUpdated的区别在于触发时机(子组件更新前 vs 后)unbind用于清理,必须移除bind中添加的事件监听器- 钩子参数中
el用于操作 DOM,binding携带指令的值、参数、修饰符等信息
存放路径:articles/VUE/进阶/自定义指令与渲染函数/指令钩子函数.md
📝 发现内容有误?点击此处直接编辑