在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')
  }
}
03-05 20:35