vue指令的实现
Vue 指令的实现原理
Vue 指令的核心是通过自定义指令机制扩展 HTML 元素的功能。指令的实现涉及编译、绑定和更新三个阶段。
注册自定义指令
全局注册通过 Vue.directive() 方法:
Vue.directive('focus', {
inserted: function (el) {
el.focus()
}
})
局部注册在组件选项中:
directives: {
focus: {
inserted: function (el) {
el.focus()
}
}
}
指令钩子函数
bind:指令第一次绑定到元素时调用inserted:被绑定元素插入父节点时调用update:所在组件 VNode 更新时调用componentUpdated:所在组件及子组件 VNode 更新后调用unbind:指令与元素解绑时调用
实现示例:v-model
v-model 是语法糖,本质是 value 绑定和 input 事件监听的组合:
Vue.directive('model', {
bind(el, binding, vnode) {
const vm = vnode.context
const { value, expression } = binding
el.value = value
el.addEventListener('input', (e) => {
vm[expression] = e.target.value
})
},
update(el, binding) {
el.value = binding.value
}
})
实现示例:v-show
v-show 通过控制元素的 display 样式实现:
Vue.directive('show', {
update(el, binding) {
el.style.display = binding.value ? '' : 'none'
}
})
指令参数传递
指令可以接收动态参数:
<div v-demo:[arg]="value"></div>
在指令中通过 binding.arg 获取参数:
bind(el, binding) {
console.log(binding.arg) // 获取动态参数
}
实现复杂指令
对于需要维护状态的指令,可以使用元素上的 dataset:
Vue.directive('drag', {
bind(el) {
el.dataset.dragging = false
el.addEventListener('mousedown', () => {
el.dataset.dragging = true
})
document.addEventListener('mouseup', () => {
el.dataset.dragging = false
})
}
})
指令最佳实践
- 优先使用组件而非复杂指令
- 避免在指令中进行 DOM 频繁操作
- 对于性能敏感操作使用 requestAnimationFrame
- 清除事件监听防止内存泄漏
指令与渲染函数
在渲染函数中通过 directives 选项使用指令:

render(h) {
return h('div', {
directives: [{
name: 'my-directive',
value: 'foo'
}]
})
}
Vue 指令系统提供了强大的 DOM 操作能力,但应谨慎使用以避免过度依赖直接 DOM 操作。






