概论
- 主要是通过一个唯一标识name或者id来过滤判断用户所处的角色是否有路由的权限或者按钮的权限
- 一般路由都有一个一个name可以作为唯一标识
- 一般按钮的话,可以自定义一个name作为标识
业务逻辑
后台通过选中路由或者按钮给角色,代表这个角色有数组中name[]的权限,用户或者部门再绑定角色,实现权限的管理
示例后台:
- 先给角色分配权限
- 再给用户分配角色,实现用户拥有该角色绑定的权限
路由过滤方式
通过路由守卫事件过滤权限路由,核心之处就是唯一标识name过滤
如下示例代码:
根据name:string[] 过滤完路由后,组合一般性可以直接访问的路由和权限路由
类似如下:
按钮权限实现方式:通过自定义指令过滤按钮是否显示来实现按钮权限
示例代码:
// permission.ts
// 引入vue中定义的指令对应的类型定义
import { Directive } from 'vue'
export const permission: Directive = {
// mounted是指令的一个生命周期
mounted(el, binding) {
// value 获取用户使用自定义指令绑定的内容
const { value } = binding
// 获取用户所有的权限按钮
const permissionBtn = wsCache.get('permission')
// 判断用户使用自定义指令,是否使用正确了
if (value && value instanceof Array && value.length > 0) {
const permissionFunc = value
//判断传递进来的按钮权限,用户是否拥有
//Array.some(), 数组中有一个结果是true返回true,剩下的元素不会再检测
const hasPermission = permissionBtn.some((btnName: any) => {
return permissionFunc.includes(btnName)
})
// 当用户没有这个按钮权限时,设置隐藏/移除这个按钮
if (!hasPermission) {
el.style.display = 'none'
// el.parentNode.removeChild(el);
}
} else {
throw new Error('need roles! Like v-permission="[\'admin\',\'editor\']"')
}
}
}
上面代码的核心就是:
const hasPermission = permissionBtn.some((btnName: any) => {
return permissionFunc.includes(btnName)
})
有权限则自定义指令让这个按钮显示,没权限则不让显示
-
按钮权限绑定 业务示例图
-
指令使用示意图
vue3 实现按钮权限指令示例代码:
import type { App, Directive, DirectiveBinding } from 'vue'
import { useI18n } from '@/hooks/web/useI18n'
import router from '@/router'
const { t } = useI18n()
const hasPermission = (value: string): boolean => {
const permission = (router.currentRoute.value.meta.permission || []) as string[]
if (!value) {
throw new Error(t('permission.hasPermission'))
}
if (permission.includes(value)) {
return true
}
return false
}
function hasPermi(el: Element, binding: DirectiveBinding) {
const value = binding.value
const flag = hasPermission(value)
if (!flag) {
el.parentNode?.removeChild(el)
}
}
const mounted = (el: Element, binding: DirectiveBinding<any>) => {
hasPermi(el, binding)
}
const permiDirective: Directive = {
mounted
}
export const setupPermissionDirective = (app: App<Element>) => {
app.directive('hasPermi', permiDirective)
}
export default permiDirective
注册指令
import type { App } from 'vue'
import { setupPermissionDirective } from './permission/hasPermi'
/**
* 导出指令:v-xxx
* @methods hasPermi 按钮权限,用法: v-hasPermi
*/
export const setupPermission = (app: App<Element>) => {
setupPermissionDirective(app)
}
按钮和路由菜单的关系业务示意图:
自定义路由的时候把按钮一个个也绑定到页面
总结
权限管理的核心就是通过一个类似allowRoutes:name:string[] 和 一个allowBtns:name:string[] 绑定给角色,通过允许的name去过滤路由或者按钮
相关文章
-
vue3 指令注册方式:https://blog.csdn.net/qq_37656005/article/details/123874181
-
vue-element-plus-admin:https://github.com/kailong321200875/vue-element-plus-admin
前端工程师、程序员