1

如何在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能显示出来,添加按钮则不能显示。


洛阳醉长安行
57 声望4 粉丝

charging...