在vue中(vue2)按钮级别的权限控制较多人的解决方案为使用指令控制
或v-if
,但这两者都有一定的弊端:
- 使用指令控制的弊端: 当按钮没有权限时只能让按钮隐藏掉(即设置display: none),不能让按钮消失,如果遇到懂行的人,只需将按钮的display值改为block则又可让按钮恢复可用
- 使用v-if控制的弊端: ①需要在每个使用按钮的地方定义判断有无权限的函数;②当按钮中的
v-if
条件过多时会增加理解代码的难度,并且还需要调用判断有无权限的函数并传递权限编码。
而使用权限控制组件就可以解决以上三个问题!
它的弊端就是:需要多包一层组件
编码解决问题
PermissionEl.vue组件代码:
<script>
export default {
name: 'PermissionEl',
props: {
permissionCode: { // 权限编码,多个编码按逗号隔开
type: String,
default: ''
}
},
computed: {
isPermissionPass(){
let flag = false;
let permissionCodeArr = (this.permissionCode || '').split(',');
if(permissionCodeArr.length == 0){
return false;
}
// 获取权限列表
let permissionList = (this.$store.getters.permissions || {}).list || [];
let codesMap = permissionList.reduce((res, item) => {
res[item.code] = item.code;
return res;
}, {});
for(let i = 0, len = permissionCodeArr.length; i < len; i++){
// 只要包含了一个权限code则表示通过了
if(permissionCodeArr[i] in codesMap){
flag = true;
break;
}
}
return flag;
}
},
render() {
let isPermissionPass = this.isPermissionPass;
// 默认渲染插槽里的内容(只取插槽里的第一个组件,
// 如果要支持多个组件的话需要包裹一层dom元素)
let renderContent = (this.$slots.default || [])[0];
// 如果插槽里没有内容或者权限未通过则渲染一个注释节点(vue的v-if指令也是这样的做法)
if(!isPermissionPass || !renderContent){
renderContent = document.createComment('-');
}
return renderContent;
}
};
</script>
使用:
<template>
<div class="home">
<h1>欢迎来到首页!</h1>
<permission-el permission-code="home_btn">
<el-button type="primary">一个权限控制的组件</el-button>
</permission-el>
</div>
</template>
export default {
name: 'Home',
components: {
PermissionEl: () => import('./PermissionEl.vue')
}
}