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实时更新权限
- 指令性能优化:防抖处理频繁更新

