如何在vue项目中通过后端的权限数据对组件中的按钮、元素进行显示隐藏? (如管理员能看到所有按钮 非管理员只能使用某些按钮),我们在登入时通过接口获得如下用户的菜单数据,包括每个菜单中有opFlag:1
代表当前此节点为菜单,否则opFlag:2
代表当前用户的这个菜单下可以显示(有权限使用)的按钮:
菜单树数据(含按钮):
{
"id": 932,
"opName": "业务管理",
"opFlag": 1,
"url": "/BusinessManagement",
"icon": "#iconscx",
"btnList": "",
"children": [ {
"id": 1041,
"opName": "客户管理",
"opFlag": 1,
"url": "/CustomerManagement",
"icon": "",
"children": [{
"id": 1160,
"opName": "删除",
"opFlag": 2,
"url": "del",
"icon": "",
"children": []
},{
"id": 1161,
"opName": "编辑",
"opFlag": 2,
"url": "edit",
"icon": "",
"children": []
}]
}, {
"id": 933,
"opFlag": 1,
"url": "/userManagement",
"icon": "",
"children": [{
"id": 934,
"opName": "用户列表",
"opFlag": 1,
"url": "",
"icon": "",
"children": [{
"id": 937,
"opName": "申请账号",
"opFlag": 1,
"url": "/userManagement/apply",
"icon": "",
"children": []
}, ]
}, ]
}]
}
这里我们不需要关注opFlag:1
的菜单数据,只关注opFlag:2
的按钮数据。
通过以上现有的按钮数据,在vuex中定义键值方式的权限表。通过mutations
把对应菜单的按钮权限数组项逐个push
到vuex中:
store.js
state: {
"/userManagement": [], //用户模块权限
"/CustomerManagement": [] //客户模块
},
mutations: {
setAuthList(state, auth) {
state[auth.name].push(auth.authList);
},
}
state中对应的键值 "url":["权限1","权限2"]
接下来需要分离出按钮数据,operations
为菜单树数据:
if(operations && operations.length > 0 && operations[0].children) {
_this.menuData = this.filterMenuData(operations[0].children);
}else {
_this.menuData = [];
}
setBtnListStore(url,auth){
//以按钮所属父级模块的url为模块名设置到vuex中,要在vuex中事先定义对应模块
if(this.$store.state[url]){
this.$store.commit('setAuthList',{name:url,authList:auth});
}
},
filterMenuData(data ){ //过滤出不含按钮的菜单数据
let _that = this;
let menuData = (function deepCopy( source,pUrl ) {
let target = []
for ( var k in source ) {
if (source.hasOwnProperty(k)) {
if ( typeof source[ k ] === 'object') {
if( Array.isArray(source)){ // 当前在cildren当中 递归深拷贝json
if(source[ k ].opFlag == 1){ //菜单 ,如果是菜单才进行下一步的深拷贝
target[ k ] = deepCopy( source[ k ] ,source.url)
}else{//按钮
if(pUrl){
_that.setBtnListStore(pUrl,source[k].url); //设置到vuex中
}
}
}else{
target[ k ] = deepCopy( source[ k ],source.url )
}
} else {
target[ k ] = source[ k ]
}
}
}
return target
})(data)
return menuData;
},
我们获取了树形的菜单数据后对菜单进行渲染同时通过filterMenuData
过滤到opFlag:2
的数据,然后通过setBtnListStore
把菜单和对应的按钮列表存储入vuex中。
对operations
菜单数据操作前先深拷贝一次,以免影响原有数据,在拷贝递归的同时获取按钮权限信息。
接下来就是撸一个vue自定义指令
,创建authVueDirective.js
用于在vue中创建自定义指令auth:
import Vue from 'vue';
let authList = []
let setAuthList = (list)=>{
//在组件中传入当前用户的权限列表
authList = list||[];
}
const hasPermission = userPermission => {
// 当前用户的权限列表
return authList.some(i => userPermission.includes(i));
};
// 权限指令
Vue.directive("auth", {
inserted: (el, binding, vnode) => {
if (!hasPermission(binding.value)) {
el.parentNode.removeChild(el);
}
}
});
export default {setAuthList}
authList
是一个用于存储权限的列表,在v-auth="['xxx']"
使用时,判断v-auth
所需的权限是否存在于authList
列表中,否则不存在表示当前无权限则移除元素(按钮),到这里我们就完成了整个按钮权限的所需工作,接下来看看如何在组件中使用它:
在/CustomerManagement
页面中引入authVueDirective.js
存储当前页面的权限列表(伪代码):
template:
<el-button @click="del"
v-auth="['del']">删除</el-button>
<el-button @click="add"
v-auth="['add']">添加</el-button>
import vauth from '@/assets/js/authVueDirective.js';
created(){
//设置按钮权限
vauth.setAuthList(this.$store.state['/CustomerManagement']);
//这里的setAuthList相当于vauth.setAuthList(['del','edit']);
},
最终删除按钮在因为我们有del
能显示出来,添加按钮则不能显示。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。