核心概念
app.directive() 是 Vue 3 中用于注册全局自定义指令的函数,通过它可以直接操作 DOM 或监听元素行为。其作用类似于封装可复用的 DOM 操作逻辑,例如自动聚焦、权限验证、动态样式等。与组件不同,指令更侧重于操作元素本身,而非封装数据和状态。
基础语法
注册全局指令
使用 app.directive('指令名', {钩子函数}) 注册指令,支持生命周期钩子和参数传递。
const app = createApp(App)
app.directive('focus', {
mounted(el) {
el.focus() // 元素挂载后自动聚焦
}
})
常用钩子函数
| 钩子函数 | 触发时机 | 说明 |
|---|---|---|
created |
指令绑定后 | 初始化配置 |
mounted |
元素挂载后 | 执行 DOM 操作 |
updated |
组件更新后 | 响应绑定值变化 |
unmounted |
元素卸载时 | 清理副作用 |
进阶特性
参数传递与修饰符
通过 binding.value 接收参数,binding.arg 获取指令后缀,binding.modifiers 处理修饰符。
app.directive('color', {
mounted(el, binding) {
if (binding.arg === 'text') {
el.style.color = binding.value // v-color:text="red" 设置文本颜色
} else if (binding.arg === 'bg') {
el.style.backgroundColor = binding.value // v-color:bg="blue" 设置背景色
}
}
})
指令组合使用
可结合多个指令,通过修饰符分离逻辑,例如同时使用 v-color:red.bold:
app.directive('bold', {
mounted(el) {
el.style.fontWeight = 'bold' // 独立实现加粗效果
}
})
实战应用
表单实时验证
创建 v-validate 指令,在输入时校验格式并提示错误:
app.directive('validate', {
mounted(el, binding) {
const rules = binding.value // 接收校验规则对象
el.addEventListener('input', () => {
if (rules.required && el.value.trim() === '') {
el.classList.add('error') // 校验失败添加样式
console.warn('必填项不能为空')
} else {
el.classList.remove('error') // 校验通过移除样式
}
})
}
})
权限控制指令
实现 v-permission 指令,根据用户角色隐藏元素:
app.directive('permission', {
mounted(el, binding) {
const userRole = 'admin' // 假设用户角色为 admin
const allowedRoles = binding.value.roles // 接收权限配置
if (!allowedRoles.includes(userRole)) {
el.remove() // 权限不足直接移除元素
}
}
})
注意事项
- 避免重复注册:全局指令名称需唯一,重复注册会覆盖原有逻辑。
- 性能问题:频繁操作 DOM 可能导致性能下降,建议在
mounted钩子中集中处理。 - 优先级控制:使用
priority属性调整多个指令的执行顺序(Vue 3 默认不支持,需手动实现)。 - 局部指令优先级更高:局部指令(组件内定义)会覆盖全局同名指令,需明确使用场景。
总结
app.directive() 函数为 Vue 3 提供了直接操作 DOM 的能力,适合封装通用行为并提升代码复用性,但需注意合理使用以避免过度耦合和性能损耗。