Vue3自定义指令深度实战:打造智能权限控制系统
一、Vue3指令系统核心优势
相比Vue2的指令系统,Vue3提供了:
- 生命周期钩子重构:更符合组合式API风格
- 参数类型强化:支持TypeScript类型推断
- 动态指令参数:v-mydirective:[arg]
- 多实例复用:通过app.directive全局注册
二、RBAC权限控制系统实现
1. 权限指令核心代码
// directives/permission.js import { useAuthStore } from '@/stores/auth' export const permission = { mounted(el, binding) { const authStore = useAuthStore() const { value } = binding if (typeof value === 'string') { if (!authStore.hasPermission(value)) { el.parentNode?.removeChild(el) } } else if (Array.isArray(value)) { const [permission, mode = 'all'] = value const hasPerm = mode === 'all' ? authStore.hasAllPermissions(permission) : authStore.hasAnyPermission(permission) if (!hasPerm) { el.parentNode?.removeChild(el) } } } } // main.js import { permission } from './directives/permission' app.directive('permission', permission)
2. Pinia权限状态管理
// stores/auth.js import { defineStore } from 'pinia' export const useAuthStore = defineStore('auth', { state: () => ({ roles: [], permissions: [] }), actions: { async fetchPermissions() { const res = await api.getUserPermissions() this.permissions = res.data }, hasPermission(perm) { return this.permissions.includes(perm) }, hasAllPermissions(perms) { return perms.every(p => this.permissions.includes(p)) }, hasAnyPermission(perms) { return perms.some(p => this.permissions.includes(p)) } } })
3. 多种权限控制场景
基础用法:按钮权限
<button v-permission="'user:create'">创建用户</button>
组合权限:多种条件
<!-- 需要同时拥有两个权限 --> <button v-permission="[['user:edit', 'user:view'], 'all']">编辑视图</button> <!-- 满足任一权限即可 --> <button v-permission="[['report:export', 'report:print'], 'any']">导出/打印</button>
路由级权限控制
// router.js router.beforeEach(async (to) => { const authStore = useAuthStore() if (to.meta?.permission) { const hasPerm = authStore.hasPermission(to.meta.permission) if (!hasPerm) return '/403' } })
三、高级功能扩展
1. 权限指令增强版
updated(el, binding) { // 权限变化时重新检查 this.mounted(el, binding) }, beforeUnmount(el) { // 清理DOM引用 el._permissionCleanup?.() }
2. 动态权限更新
watch(() => authStore.permissions, () => { // 权限变更时重新检查所有指令 document.querySelectorAll('[v-permission]').forEach(el => { const instance = getCurrentInstance() instance?.proxy?.$forceUpdate() }) })
四、企业级实践建议
- 权限编码规范:模块:操作 如 system:user:delete
- 后端校验兜底:前端控制仅为体验优化
- 权限变更通知:WebSocket实时更新权限
- 指令性能优化:防抖处理频繁更新