generate-menus.ts 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import type { Router, RouteRecordRaw } from 'vue-router';
  2. import type {
  3. ExRouteRecordRaw,
  4. MenuRecordRaw,
  5. RouteMeta,
  6. } from '@vben-core/typings';
  7. import { filterTree, mapTree } from '@vben-core/shared/utils';
  8. /**
  9. * 根据 routes 生成菜单列表
  10. * @param routes - 路由配置列表
  11. * @param router - Vue Router 实例
  12. * @returns 生成的菜单列表
  13. */
  14. function generateMenus(
  15. routes: RouteRecordRaw[],
  16. router: Router,
  17. ): MenuRecordRaw[] {
  18. // 将路由列表转换为一个以 name 为键的对象映射
  19. const finalRoutesMap: { [key: string]: string } = Object.fromEntries(
  20. router.getRoutes().map(({ name, path }) => [name, path]),
  21. );
  22. let menus = mapTree<ExRouteRecordRaw, MenuRecordRaw>(routes, (route) => {
  23. // 获取最终的路由路径
  24. const path = finalRoutesMap[route.name as string] ?? route.path ?? '';
  25. const {
  26. meta = {} as RouteMeta,
  27. name: routeName,
  28. redirect,
  29. children = [],
  30. } = route;
  31. const {
  32. activeIcon,
  33. badge,
  34. badgeType,
  35. badgeVariants,
  36. hideChildrenInMenu = false,
  37. icon,
  38. link,
  39. order,
  40. title = '',
  41. } = meta;
  42. // 确保菜单名称不为空
  43. const name = (title || routeName || '') as string;
  44. // 处理子菜单
  45. const resultChildren = hideChildrenInMenu
  46. ? []
  47. : ((children as MenuRecordRaw[]) ?? []);
  48. // 设置子菜单的父子关系
  49. if (resultChildren.length > 0) {
  50. resultChildren.forEach((child) => {
  51. child.parents = [...(route.parents ?? []), path];
  52. child.parent = path;
  53. });
  54. }
  55. // 确定最终路径
  56. const resultPath = hideChildrenInMenu ? redirect || path : link || path;
  57. return {
  58. activeIcon,
  59. badge,
  60. badgeType,
  61. badgeVariants,
  62. icon,
  63. name,
  64. order,
  65. parent: route.parent,
  66. parents: route.parents,
  67. path: resultPath,
  68. show: !meta.hideInMenu,
  69. children: resultChildren,
  70. };
  71. });
  72. // 对菜单进行排序,避免order=0时被替换成999的问题
  73. menus = menus.sort((a, b) => (a?.order ?? 999) - (b?.order ?? 999));
  74. // 过滤掉隐藏的菜单项
  75. return filterTree(menus, (menu) => !!menu.show);
  76. }
  77. export { generateMenus };