vue自定义指令是封装dom操作逻辑的高效方式,适合聚焦管理、权限控制等跨组件复用场景,通过v-focus、v-permission等语义化标签实现声明式调用,支持局部与全局注册,兼顾原生元素与封装组件适配,并需注意渲染时机、权限校验、类型检查及生命周期细节。

Vue自定义指令是封装 DOM 操作逻辑的高效方式,特别适合聚焦管理、权限控制这类跨组件复用的场景。它把“什么时候操作”和“怎么操作”打包成一个语义清晰的标签,比如 v-focus 或 v-permission,模板里一写就生效,不用每个组件都重复写 ref、mounted、权限判断。
聚焦指令:适配原生与封装组件
自动聚焦看似简单,但实际要兼顾不同输入组件的结构差异。原生 <input> 可直接调用 focus();而 Element Plus 的 <el-input></el-input> 内部输入框不是根元素,需主动查找。
- 安全写法:在
mounted钩子中用el.querySelector('input') || el.querySelector('.el-input__inner')获取真实输入节点 - 渲染时机更稳妥:包裹在
requestAnimationFrame中执行聚焦,避免因 DOM 尚未完成绘制导致失效 - 局部使用时,定义为
const vFocus = { mounted(el) { /* 上述逻辑 */ } },模板中写<el-input v-focus></el-input>
权限指令:按角色动态控制元素显隐
权限指令的核心是比对当前用户权限与绑定值(如所需角色或操作码),再决定是否保留该 DOM 元素。常见做法是移除无权限的节点,而不是仅设 display: none,避免敏感内容被审查源码发现。
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
- 绑定写法示例:
<button v-permission="['admin', 'editor']">删除</button> - 指令内通过
binding.value获取所需权限数组,从 Vuex store 或 pinia 中读取当前用户权限列表 - 权限校验用
some()判断交集,不匹配则执行el.parentNode?.removeChild(el) - 建议加类型检查:若
binding.value不是数组,抛错提示,防止误传字符串或空值
注册方式:按需选择局部或全局
局部指令适合实验性功能或仅在少数页面使用的逻辑;全局指令更适合聚焦、权限、防抖等基础能力,一次注册全项目可用。
- 局部注册:在
<script setup></script>中声明变量名以v开头且驼峰命名(如vPermission),模板中用短横线写法(v-permission) - 全局注册:在
main.js/ts中调用app.directive('permission', { ... }),注册后任意组件无需引入即可使用 - 注意命名冲突:全局指令名不带
v-前缀,Vue 会自动识别v-permission对应'permission'
关键细节不能漏
写指令不是只写个 mounted 就完事。几个容易出问题的地方得盯住:
-
el是原生 DOM 元素,不是 Vue 组件实例,不能调用组件方法或访问this - 权限指令若用于异步加载的用户信息(比如登录后才获取角色),需监听变化或配合
updated钩子做二次校验 - 聚焦指令在 Tab 切换、路由复用等场景下可能触发多次,可加标记位或检查
document.activeElement避免干扰用户操作 - 指令中避免直接修改 props 或响应式数据,如需通信,可通过事件或 provide/inject
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










