当前位置: 首页 > Web前端 > vue.js

Vuex+自定义指令实现按钮粒度权限控制

时间:2023-04-01 13:01:03 vue.js

vue项目中如何通过后台权限数据显示和隐藏组件中的按钮和元素?(比如管理员可以看到所有按钮,非管理员只能使用某些按钮),我们在登录时通过接口获取如下用户菜单数据,其中每个菜单中包含opFlag:1表示当前节点为菜单,otherwiseopFlag:2代表当前用户这个菜单下可以显示(有权限)的按钮:菜单树数据(包括按钮):{"id":932,"opName":"BusinessManagement","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":"edit","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中定义key-value方式的权限表。通过mutations将对应菜单的按钮权限数组项一一推送到vuex中:store.jsstate:{"/userManagement":[],//用户模块权限"/CustomerManagement":[]//客户模块},突变:{setAuthList(state,auth){state[auth.name].push(auth.authList);},}state中对应的key值"url":["authority1","authority2"]需要隔开next输出按钮数据,operations为菜单树数据:if(operations&&operations.length>0&&操作[0].children){_this.menuData=this.filterMenuData(操作[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;letmenuData=(functiondeepCopy(source,pUrl){lettarget=[]for(varkinsource){if(source.hasOwnProperty(k)){if(typeofsource[k]==='object'){if(Array.isArray(source)){//cildren中的当前递归深度复制jsonif(source[k].opFlag==1){//menu,如果是菜单,则进行下一次深拷贝,来源[k].url);//设置为vuex}}}else{target[k]=deepCopy(source[k],source.url)}}else{target[k]=source[k]}}}returntarget})(data)returnmenuData;},我们通过过滤器获取树形菜单数据,同时渲染菜单MenuData过滤opFlag:2的数据,然后通过setBtnListStore将菜单和对应的按钮列表存储到vuex中。在对操作菜单数据进行操作前,先深拷贝一次,以免影响原有数据,递归拷贝的同时获取按键权限信息。接下来就是创建vue自定义指令,创建authVueDirective.js在vue中创建自定义指令auth:importVuefrom'vue';letauthList=[]letsetAuthList=(list)=>{//组件中传入当前用户的权限列表authList=list||[];}consthasPermission=userPermission=>{//当前用户的权限列表returnauthList.some(i=>userPermission.includes(i));};//权限指令Vue.directive("auth",{inserted:(el,binding,vnode)=>{if(!hasPermission(binding.value)){el.parentNode.removeChild(el);}}});exportdefault{setAuthList}authList是一个用来存储权限的列表。当使用v-auth="['xxx']"时,判断authList列表中是否存在v-auth需要的权限,否则不存在,说明当前没有权限移除元素(按钮),到这里我们就完成了整个按钮权限所需要的工作。接下来看看在组件中如何使用:在/CustomerManagement页面引入authVueDirective.js存放当前页面的权限列表(伪代码):template:删除添加从'@/导入vauthassets/js/authVueDirective.js';created(){//设置按钮权限vauth.setAuth列表(this.$store.state['/CustomerManagement']);//这里的setAuthList相当于vauth.setAuthList(['del','edit']);},最后的删除按钮在这里,因为我们有del要显示出来,添加按钮不能显示