vue3权限管理-按钮权限+自定义指令

2,277 阅读3分钟

按钮权限在项目中是一种非常常见的需求,通常情况下,我们通过自定义指令的方式完成。
整个流程在我看来主要是以下几个步骤:

  1. 获取权限
  2. 将权限存入本地
  3. 创建权限自定义指令
  4. 全局挂载自定义指令
  5. 在dom上使用

一:获取权限

通过接口获取到定义好的权限字段,通常都是菜单权限加按钮权限,将按钮权限的字段筛选出来

二:将权限存在本地

将按钮权限筛选出来之后,存到本地

// 1,先判断本地是否存在,存在先进行删除,防止不同用户登录时权限耦合
if(localStorage.getItem(LOCAL_PERMISSION_KEY)){
    localStorage.removeItem(LOCAL_PERMISSION_KEY)
  }
// 2,对获取的权限进行筛选,具体操作根据获取的数据来  
  const buttonPrivilege = arr.filter(item =>item.resourceType=="BUTTON").map(item=>item.code)
// 3,将筛选出的权限转换为json格式,存到本地
  localStorage.setItem(LOCAL_PERMISSION_KEY, JSON.stringify(buttonPrivilege))

三:创建权限自定义指令

创建自定义指令的方法都是一样的,唯一的差别可能是每个人的代码风格不同,所以书写的方式也不一样,我这里也是自己的书写方式,可以根据我的方法自行修改

通过app.directive('你的指令名称', 指令定义对象)可以创建一个全局自定义指令,我这里是将指令定义对象提取出来了

/**
 * @plugins/index.ts
 * 我创建了一个plugins文件夹,在文件夹中定义了index.ts文件,并将需要挂载的函数暴露出去,以后有需要全局挂载的文件都可以放到这个文件夹中,并在这个文件里暴露出去
 */
export { setupDirectives } from './directives';
/**
 * @plugins/directive.ts
 * 我创建了一个plugins文件夹,在文件夹中定义了directive.ts文件并在index文件中暴露函数setupDirectives,以后要是有其他全局文件,都可以放到这个文件夹中一起管理
 */
 
import { App } from 'vue';
import { permission } from '@/directives/permission';
import { focus } from '@/directives/focus';
/**
 * 注册全局自定义指令
 * @param app
 * 我这里的指令定义对象permission是从另一个文件夹中导入的,如果有其他自定义指令,都可以直接在setupDirectives函数中书写
 */
export function setupDirectives(app: App) {
  // 权限控制指令
  app.directive('permission', permission);
  app.directive('focus', focus);
}

app.directive('你的指令名称', 指令定义对象),指令定义对象里面是一个类似组件生命周期的钩子函数,如果想了解详情可以去vue官网了解,我这里用的是mounted()这个函数,它在所有节点挂载完成后调用,这个函数mounted(el, binding, vnode, prevVnode)有四个参数,具体参数值可去vue官网查看

/**
 * @directives/permission.ts
 * 我创建了一个directives文件夹,用来存放所有的全局自定义指令
 */
 
import { ObjectDirective } from 'vue';
import { usePermission } from '@/hooks/usePermission';

/**
 * @el:获取绑定的dom
 * @binding.value:通过指令绑定之后传过来的参数
 * 具体的权限判断代码我放到hasPermission()函数中
 */

export const permission: ObjectDirective = {
  mounted(el: HTMLButtonElement, binding) {
    if (binding.value == undefined) return;
    const code = binding.value;
    const { hasPermission } = usePermission();
    // 将获取到的值传到权限判断函数中,如果函数返回false,删除dom
    if (!hasPermission(code)) {
      el.remove();
    }
  },
};
/**
 * @hooks/usePermission.ts
 * @getStoreData:用来取出之前存好的按钮权限并转换格式
 * @usePermission:用来判断是否拥有权限
 */
 
function getStoreData(dataKey) {
  const permissionsStr = localStorage.getItem(dataKey)
  const permissions=JSON.parse(permissionsStr)
  // console.log(permissions)
  return {
    permissions
  }
}

export function usePermission() {

  const {permissions}= getStoreData(LOCAL_PERMISSION_KEY);
  /**
   * 判断是否存在权限
   * 可用于 v-if 显示逻辑
   * */
  function hasPermission(code): boolean {
  // 如果没有code,直接返回true
    if (!code) return true;
    if(permissions&&permissions.length>0){
  // 判断传过来的值是否在获取的权限中,在就返回true,否则返回false
      return permissions.indexOf(code) >-1? true : false;
    }
    return false;
  }
  return { hasPermission };
}

四:全局挂载自定义指令

/**
   * 导入plugins文件夹中的index文件,并提取setupDirectives函数,将创建好的app实列通过参数传过去
   * */
   
import { setupDirectives } from './plugins'
const app = createApp(App)
//注册指令
setupDirectives(app)

五:在dom上使用

<n-checkbox v-permission="'定义好的权限字段'" />

以上就是我做按钮权限的全部流程,如果有什么问题,欢迎大家一起讨论交流