使用element-plus-admin 路由过滤 实现

127 阅读3分钟

使用test角色 通过前端控制菜单权限

image.png deep 将树状列表通过递归函数遍历 并返回前端所需要用到的path,name,sort字段组成新数组 flatTree 将一个多维嵌套的数组扁平化为一个一维数组 keyBy:lodash中keyBy 函数将这个数组转换成一个以 menuPath 属性值为键的对象,每个键对应一个元素对象作为其值。 www.lodashjs.com/docs/lodash… 这个 titleMap 对象可以被用作一个映射表,例如当需要根据某个 menuPath 查找对应的元素时,可以直接通过 titleMap[menuPath] 来获取对应的元素对象。这样,在查找元素时,就不需要每次遍历整个数组,而是直接访问空间复杂度为 O(1) 的对象即可,这样可以提高查找效率。 setFullPath:该函数对传入的异步路由表进行递归遍历,对每个路由对象的 fullPath 属性进行填充,同时对每个路由对象的 meta 属性进行修改。如果该路由对象具有子路由,则递归调用 setFullPath 函数,将父级路由的 path 属性与当前路由对象的 path 属性拼接成新路径,并将其作为父级路由路径传入函数中。

最后,将填充完整的异步路由表数组根据 menuSort 属性进行排序,返回排序后的异步路由表数组。

需要注意的是,由于代码中引用了一个名为 titleMap 的对象,因此需要确保该对象已在当前作用域内定义。

export function deep(datas, newArr) {
  // const newArr = []
  datas.forEach((items) => {
    if (items) {
      newArr.push(items.menuPath)
      if (items.children) {
        deep(items.children, newArr)
      }
    }
  })
  return newArr
}
const flatTree = (arr:any, res:any = []) => {
        arr.forEach(x => {
          res.push({ menuPath: x.menuPath, menuName: x.menuName, menuSort: x.menuSort })
          if (x.children) flatTree(x.children, res)
        })
        return res
      };
       const titleMap = keyBy(flatTree(wsCache.get('roleMenu')) , 'menuPath')
const setFullPath = (arr, path = '') =>arr.map((x) =>  x.children
          ? { ...x,
              fullPath: path ? `${path}/${x.path}` : x.path,
              meta: {
                ...x.meta,
                title:  titleMap[[path, x.path].filter(Boolean).join('/')]?.menuName || x.meta?.title
              },
              children: setFullPath(x.children, path ? path + x.path : x.path).sort(
                (b,a) => titleMap[b.fullPath]?.menuSort - titleMap[a.fullPath]?.menuSort
              )
            }
          : {
              ...x,
              fullPath: [path, x.path].filter(Boolean).join('/'),
              meta: {
                ...x.meta,
                title:  titleMap[[path, x.path].filter(Boolean).join('/')]?.menuName || x.meta?.title
              }
            }
      )
      .sort((b,a ) => {
        if (titleMap[a.fullPath]?.menuSort && !titleMap[b.fullPath]?.menuSort) return -1
        if (titleMap[b.fullPath]?.menuSort && !titleMap[a.fullPath]?.menuSort) return 1
        return titleMap[b.fullPath]?.menuSort - titleMap[a.fullPath]?.menuSort
      })
     cosnt  routerMap = generateRoutesFn1(setFullPath(cloneDeep(asyncRouterMap)), routers as string[])
     /**
     这行代码是对 `generateRoutesFn1` 函数的调用,其中传入了两个参数:

-   经过 `cloneDeep` 处理后,将异步路由表的 `fullPath` 属性填充完整的数组 `asyncRouterMap`。
-   字符串数组 `routers`,用于存储动态添加的路由,一般在页面内调用 router 的 API 进行添加。

`generateRoutesFn1` 函数的作用是根据用户权限及异步路由表生成可访问的路由表,返回可访问路由表数组。这个函数大概的实现流程是:

1.  通过 `asyncRouterMap` 中的 `meta` 属性获取当前用户可以访问的路由表。
1.  将异步路由表转换为可访问路由表,即删除没有访问权限的路由及其子路由。
1.  将动态添加的路由合并到可访问路由表中。
1.  返回可访问路由表数组。

需要注意的是,这里我们看不到 `generateRoutesFn1` 的具体实现,如果您需要关注该函数的实现细节,可以找到项目中对应的源代码。
     */
     //  重命名
          const setTitle = (arr, path = '') => {
            arr.forEach((x) => {
              const fullPath = [path, x.path].filter(Boolean).join('/')
              x.meta.title = titleMap[fullPath]?.menuName || x.meta.title
              x.fullPath = fullPath
              if (x.children) {
                setTitle(x.children, fullPath)
              }
            })
          }
           setTitle(routerMap)
          //  排序
          const sortFun = (b,a) => {
            if (titleMap[a.fullPath]?.menuSort && !titleMap[b.fullPath]?.menuSort) return -1
            if (titleMap[a.fullPath]?.menuSort && !titleMap[b.fullPath]?.menuSort) return 1
            return titleMap[b.fullPath]?.menuSort - titleMap[a.fullPath]?.menuSort
          }
          const sortMenu = (arr) => {
            arr.sort(sortFun)
            arr.forEach((x) => {
              if (x.children) {
                sortMenu(x.children)
              }
            })
          }
          sortMenu(routerMap)