本文已参加「信任创作礼」活动,一起开启创作之路。
最近项目中遇到了按钮权限办理的需求,整理了一下目前的计划,有不对的当地望咱们指出~
计划1:数组+自定义指令
把权限放到数组中,经过vue的自定义指令来判别是否具有该权限,有则显现,反之则不显现
咱们能够把这个按钮需求的权限放到组件上
<el-button
v-hasPermi="['home:advertising:update']"
>新建</el-button>
自定义指令:
逻辑就是咱们在登陆后会获取该用户的权限,并存储到localStorage中,当一个按钮展示时会判别localStorage存储的权限列表中是否存在该按钮所需的权限。
/**
* 权限处理
*/
export default {
inserted(el, binding, vnode) {
const { value } = binding;
const SuperPermission = "superAdmin"; // 超级用户,用于开发和测验
const permissions = localStorage.getItem('userPermissions')&& localStorage.getItem('userPermissions').split(',');
// 判别传入的组件权限是否符合要求
if (value && value instanceof Array && value.length > 0) {
const permissionFlag = value;
const hasPermissions = permissions && permissions.some(permission => all_permission === permission || permissionFlag.includes(permission));
// 判别是否有权限是否要展示
if (!hasPermissions) {
el.parentNode && el.parentNode.removeChild(el);
}
} else {
throw new Error(`请设置操作权限标签值`);
}
},
};
注册权限
import Vue from 'vue';
import Vpermission from "./permission";
// 按钮权限 自定义指令
Vue.directive('permission', Vpermission);
关于路由权限
数组的计划也能够用到菜单权限上,能够在路由的meta中携带该路由所需的权限,例如:
const router = [{
path: 'needPermissionPage',
name: 'NeedPermissionPage',
meta: {
role: ['permissionA', 'permissionB'],
},
}]
这个时分就需求在烘托权限的时分动态烘托了,该计划能够看一下其他的文章或成熟的项目,写的非常好
计划2: 二进制
经过二进制来操控权限:
假定咱们有增删改查四个基本权限:
const UPDATE = 0b000001;
const DELETE = 0b000010;
const ADD = 0b000100;
const SEARCH = 0b001000;
每一位代表是否有该权限,有该权限则是1,反之是0
表达权限:
咱们能够运用或运算来表达一个权限结果,或运算:两个任何一个为1,结果就为1
const reslut = UPDATE | DELETE | SEARCH;
console.log(reslut); // 11
变成了十进制,咱们能够经过toString方法变为二进制结果
const reslut = UPDATE | DELETE | SEARCH;
console.log(reslut.toString(2)); // 1011
result 这个结果就代表咱们既具有更新权限,一起也具有删除和查询的权限
那么咱们能够将十进制的reslut当作该用户的权限,把这个结果给后台,下次用户登陆后只需求回来这个结果就能够了。
权限判别
咱们了解了怎么表达一个权限,那怎么做权限的判别呢?
能够经过且运算,且运算:两位都为1,这一位的结果才是1。
还是用上面的结果,当咱们从接口中拿到了reslut,判别他是否有 DELETE 权限:
console.log((reslut & DELETE) === DELETE); // true
是否有新增的权限
console.log((result & ADD) === ADD); // false
判别和运用
/**
* 接受该组件所需的权限,回来用户权限列表是否有该权限
* @param {String} permission
* @returns {Boolean}
*/
function hasPermission(permission) {
const permissionList = {
UPDATE: 0b000001,
DELETE: 0b000010,
CREATE: 0b000100,
SEARCH: 0b001000
}
let btnPermission = permissionList[permission] ? permissionList[permission] : -1;
if (btnPermission === -1) return false;
const userPermission = localStorage.getItem('userPermissions');
// 将本地十进制的值转换为二进制
const userPermissionBinary = userPermission.toString(2);
// 比照组件所需权限和本地存储的权限
return (userPermissionBinary & btnPermission) === btnPermission;
}
直接在组件中经过v-show/v-if来操控是否展示
<el-button v-show="hasPermission('UPDATE')">更新</el-button>
小结
我了解来说,关于计划1来说,计划2的优势在于更简洁,后台仅需求存储一个十进制的值,但假如后期新增需求更新了新的权限,可能需求调整二进制的位数来满意事务需求。计划1的优势在于更加易懂,新增权限时仅需求更新组件自定义指令的数组。