上一篇文章《从零开始Vue3+Element Plus后台管理系统(18)——权限路由实现》已经实现了页面路由的权限控制。除此之外,我们还需要更细粒度的控制,比如对按钮、链接、某个字段的显示做更加细致的控制。
在实际场景中,常用以下两种判断方式
在template模板中,一般使用指令可以直接控制按钮级别元素的显示
通常在登录成功后,我们会获取细粒度的指令code和用户角色role,我们它放在userStore中,
// store/user.ts
...
// 模拟几个权限code和角色
let role = 'super'
let permiss = ref(['btn_more', 'btn-edit', 'btn-delelte'])
...
v-permiss指令用于判断用户store保存的permiss和当前指令binding的值是否匹配,如果不匹配就移除该元素。
<el-link v-permiss="['btn_more']">查看更多el-link>
<el-link v-permiss="['btn_more1']">查看更多el-link>
指令代码实现
import { DirectiveBinding } from 'vue'
import { useUserStore } from '~/store/user'
export default {
mounted(el: HTMLElement, binding: DirectiveBinding) {
const val = binding.value
const useUser = useUserStore()
const permiss = useUser.permiss
const parentEl = el.parentElement
let flag = true
// 可以传入字符串和数组
if (typeof val === 'string') {
flag = permiss.includes(val)
} else {
// 如果传入数组,只要数组中任意一个值和当前permiss code或者role匹配就会显示。
flag = val.some((item: string) => permiss.includes(item))
}
// 如果不匹配,移除该元素
if (!flag) parentEl?.removeChild(el)
}
}
v-auth指令用于判断当前值是否匹配用户角色role,不匹配就不显示。它和v-permiss如此相似,以至于我想把它们俩合成一个。但是在使用时就麻烦一点点,还是分开比较清晰。
import { DirectiveBinding } from 'vue'
import { useUserStore } from '~/store/user'
export default {
mounted(el: HTMLElement, binding: DirectiveBinding) {
const val = binding.value
const useUser = useUserStore()
const role = useUser.role
const parentEl = el.parentElement
console.log(useUser.role, el, parentEl, binding.value, typeof val)
let flag = true
// 可以传入字符串和数组
if (typeof val === 'string') {
flag = role === val
} else {
flag = val.includes(role)
}
if (!flag) parentEl?.removeChild(el)
}
}
有的情况不能通过指令控制元素,而是要通过v-if,或者直接在js文件中做细粒度的判断。所以除了指令,我们还需要导出一个普通js方法。
本项目GIT地址:https://github.com/lucidity99/mocha-vue3-system
如果有帮助,给个star ✨ 点个赞