欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

自定义指令实现vue项目中的按钮级权限

程序员文章站 2022-06-08 10:37:20
...

vue项目中通过自定义指令实现按钮的显示/隐藏,按钮角色是保存在vuex中的(正常是通过登陆接口返回塞进去的)。

import Vue from 'vue'
import store from './store'
import route from './router'
const customDirective = () => {
  // 注册一个全局自定义指令 `v-focus`,默认focus
  Vue.directive('focus', {
    inserted: function (el) {
      el.focus()
    }
  });
  // 控制按钮显示和隐藏
  Vue.directive('has', {
    // 当被绑定的元素插入到 DOM 中时……
    inserted: function (el, binding: any, vnode: any) {
      const roleFunction: string = (store.state as any).common.roleFunction;
      let rolePromissions: Array<any> = [];
      if (roleFunction) {
        rolePromissions = JSON.parse(roleFunction);
      }
      // let btnPermissions: Array<any> = vnode.context.$route.meta.btnPermissions || [];
      let btnPermissions: Array<any> = [];
      // 递归遍历router数据获取最新的meta...原因在于切换用户后虚拟节点依旧是老的节点
      const resusion: Function = (data: Array<any>, currentRoute: string) => {
        data.forEach(item => {
          const path: string = item.path;
          if (path === currentRoute) {
            const meta: any = item.meta;
            btnPermissions = meta.btnPermissions || [];
          } else {
            const children: Array<any> = item.children;
            if (children && children.length > 0) {
              resusion(children);
            }
          }
        })
      }
      resusion((route as any).options.routes, vnode.context.$route.path);

      const unionPromissions: Array<any> = Array.from(new Set(rolePromissions.map(item => {
        return item.btnName
      }).concat((btnPermissions as Array<any>).map(item => {
        return item.btnName;
      }))));
      const currentBtnValue: string = binding.value;
      if (unionPromissions.length > 0 && currentBtnValue !== 'btn_undefined') {
        if (unionPromissions && unionPromissions.indexOf(currentBtnValue) < 0) {
          // 开发过程中去掉这里todo
          (el as any).parentNode.removeChild(el);
        }
      }
    }
  })
};
export default customDirective

Vue.use(customDirective)