generate-menus.ts 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import type { ExRouteRecordRaw, MenuRecordRaw } from '@vben-core/typings';
  2. import type { RouteRecordRaw, Router } from 'vue-router';
  3. import { mapTree } from '@vben-core/toolkit';
  4. /**
  5. * 根据 routes 生成菜单列表
  6. * @param routes
  7. */
  8. async function generateMenus(
  9. routes: RouteRecordRaw[],
  10. router: Router,
  11. ): Promise<MenuRecordRaw[]> {
  12. // 将路由列表转换为一个以 name 为键的对象映射
  13. // 获取所有router最终的path及name
  14. const finalRoutesMap: { [key: string]: string } = Object.fromEntries(
  15. router.getRoutes().map(({ name, path }) => [name, path]),
  16. );
  17. let menus = mapTree<ExRouteRecordRaw, MenuRecordRaw>(routes, (route) => {
  18. // 路由表的路径写法有多种,这里从router获取到最终的path并赋值
  19. const path = finalRoutesMap[route.name as string] ?? route.path;
  20. // 转换为菜单结构
  21. // const path = matchRoute?.path ?? route.path;
  22. const { meta, name: routeName, redirect, children } = route;
  23. const {
  24. badge,
  25. badgeType,
  26. badgeVariants,
  27. hideChildrenInMenu = false,
  28. icon,
  29. link,
  30. order,
  31. title = '',
  32. } = meta || {};
  33. const name = (title || routeName || '') as string;
  34. // 隐藏子菜单
  35. const resultChildren = hideChildrenInMenu
  36. ? []
  37. : (children as MenuRecordRaw[]);
  38. // 将菜单的所有父级和父级菜单记录到菜单项内
  39. if (resultChildren && resultChildren.length > 0) {
  40. resultChildren.forEach((child) => {
  41. child.parents = [...(route.parents || []), path];
  42. child.parent = path;
  43. });
  44. }
  45. // 隐藏子菜单
  46. const resultPath = hideChildrenInMenu ? redirect || path : link || path;
  47. return {
  48. badge,
  49. badgeType,
  50. badgeVariants,
  51. icon,
  52. name,
  53. order,
  54. parent: route.parent,
  55. parents: route.parents,
  56. path: resultPath as string,
  57. children: resultChildren || [],
  58. };
  59. });
  60. // 对菜单进行排序
  61. menus = menus.sort((a, b) => (a.order || 999) - (b.order || 999));
  62. return menus;
  63. }
  64. export { generateMenus };