业务层-hooks封装之useAuth

461 阅读2分钟

名称:useAuth

功能说明: 权限相关,输入权限编码,输出权限状态,目前只支持菜单权限获取

第一版实现

import { BaseStore } from '@basic-library'

/**|
 * 权限控制
 * @param code 权限编码
 */
const useAuth = (code) => {
    const item = BaseStore.auth.getInfoByCode(code)
    if (!item) return
    return true
};

export default useAuth

上述代码,有遇到 BaseStore.auth.getInfoByCode(code),可能大家就有点懵了,这个是属于框架层

basic-library:通用接口、状态、方法服务

我们来看看, BaseStore.auth.getInfoByCode的简易化代码实现,后续到讲basic-library的时候,在细讲其设计思路和相关方法论

import produce, { enableMapSet } from "immer";
import { formatAuthData, computeTreeList } from "./utils";
import { orderBy } from "lodash";

enableMapSet();
// auth 权限映射
const _AUTH_STORE_ = {
  dataMap: new Map(),
  nameToCode: new Map(),
  codeToName: new Map(),
};

let authStore = produce(_AUTH_STORE_, () => {});

window._AUTH_STORE_ = authStore;

class menu {
  constructor() {
    this.updateTime = 0;
  }

  updateDepHolder() {
    this.updateTime = Date.now();
  }

  ...功能方法省略

  /**
   * 根据权限编码获取菜单对象
   * @param {*} code 
   * @returns 
   */
  getInfoByCode(code) {
    return authStore.dataMap.get(code);
  }

  /**
   * 初始化权限数据
   * @param {*} menus
   * @param {*} privileges
   */
  initAuthData(features = []) {
    authStore = produce(authStore, (draftState) => {
      const { formatMap, nameToCode, codeToName } = formatAuthData(features);
      draftState.dataMap = new Map(formatMap);
      draftState.nameToCode = new Map(nameToCode);
      draftState.codeToName = new Map(codeToName);
    });
    this.updateDepHolder();
  }
}

export { authStore };

export default new menu();

第二版实现:

主要是针对这个hooks,是否还有优化的空间,试着多想一下,对于后续功能开发过程中,可能会遇到的场景,默认传入是一个权限code编码,可覆盖大部分场景,有没有场景需要根据多个code控制,但是这个场景是什么样的?

  • 某个页面内的按钮,受控于其他一个菜单或者多个菜单的权限?
    内心独白:感觉有点不太可能出现,这种页面内的按钮,权限控制都是受控于当前页面,也就是页面内的按钮权限
  • 全局的按钮或者功能,受控于其他一个菜单或者多个菜单的权限?
    内心独白:感觉可能出现,这个几率大一些,想到了一个业务场景,但是,这类

内心纠结中...

入口的code权限码,支持数组方式就可以了 代码里面,判断入参的方式如下,使用上都是可以的:

typeof defaultValue == 'string'
typeof defaultValue == 'object'
Array.isArray(defaultValue) ---ES6提供内置判断方法

看具体的实现代码:

import { BaseStore } from '@basic-library'

/**
 * 权限控制
 * @param code 权限编码 String|Array
 */
const useAuth = (code) => {
  let cds = []
  
  if(Array.isArray(code)){
    cds = code
  }else{
    cds.push(code)
  }

  return cds.some((cd)=>BaseStore.auth.getInfoByCode(cd))
};

export default useAuth

测试结果-通过

微信截图_20220816175110.png

总结:

用到了,数组的 isArray 和 some方法

some() 方法会依次执行数组的每个元素:

  • 如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。
  • 如果没有满足条件的元素,则返回false。

注意: some() 不会对空数组进行检测。

注意: some() 不会改变原始数组。