前言
权限功能是我们经常会碰到的需求,最近也是有做一套权限系统,在此做个总结
设计
权限一般分为页面路由权限和按钮级权限。
-
页面路由权限 在项目中可以和后端约定好账号角色,为每个角色分配不同的权限,然后通过全局的路由守卫来判断拦截即可
-
按钮级权限 同样也和后端约定好按钮权限名称,我用的是'system:page1:add'这样的形式来描述系统的按钮位置,然后通过自定义指令判断一下即可
实现
- 页面路由权限
路由如果需要权限识别的话,首先要设置meta属性,用roles字段来表示可以访问该页面的角色
const routes = [
{
path: "/page1",
name: "page1",
component: () =>
import(
/* webpackChunkName: "Page1" */ "@/views/page1.vue"
),
meta: {
roles: ['admin', 'manager']
}
}
]
接着通过路由守卫来判断是否有权限,没有权限则重定向到无权限页面
const router = createRouter({
history: createWebHashHistory(),
routes,
});
router.beforeEach((to, from, next) => {
const roles = store.getters && store.getters.roles
if (to.meta.roles) {
const hasPermission = to.meta.roles.some((el) => {
return roles.includes(el)
})
if (hasPermission) {
next()
} else {
next({ path: '/404' })
}
} else {
next()
}
})
- 按钮级权限
设计一个自定义指令:
import store from '@/store'
export default {
mounted (el, binding) {
const { value } = binding
const all_permission = "*:*:*";
const permissions = store.getters && store.getters.permissions
if (value && value instanceof Array && value.length > 0) {
const permissionFlag = value
const hasPermissions = permissions.some(permission => {
console.log(all_permission, permission, permissionFlag)
return all_permission === permission || permissionFlag.includes(permission)
})
if (!hasPermissions) {
el.parentNode && el.parentNode.removeChild(el)
}
} else {
throw new Error(`请设置操作权限标签值`)
}
}
}
全局注册自定义指令
import hasPermi from './hasPermi'
const directives = {
hasPermi
}
export default {
install(app) {
Object.keys(directives).forEach((key) => {
app.directive(key, directives[key])
});
}
}
import directives from '@/directives/index.js'
const app = createApp(App)
app.use(directives).use(router).use(store).mount('#app')
使用方式
<template>
111
<h1 v-hasPermi="['system:page1:title']">wefrgty</h1>
</template>
<script>
export default {
}
</script>
<style>
</style>