menuHelper.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import { AppRouteModule } from '@jeesite/core/router/types';
  2. import type { MenuModule, Menu, AppRouteRecordRaw } from '@jeesite/core/router/types';
  3. import { findPath } from '@jeesite/core/utils/helper/treeHelper';
  4. import { isUrl } from '@jeesite/core/utils/is';
  5. import { RouteParams } from 'vue-router';
  6. import { toRaw } from 'vue';
  7. export function getAllParentPath<T = Recordable>(treeData: T[], path: string) {
  8. const menuList = findPath(treeData, (n) => n.path === path) as Menu[];
  9. return (menuList || []).map((item) => item.path);
  10. }
  11. function joinParentPath(menus: Menu[], parentPath = '') {
  12. for (let index = 0; index < menus.length; index++) {
  13. const menu = menus[index];
  14. // https://next.router.vuejs.org/guide/essentials/nested-routes.html
  15. // Note that nested paths that start with / will be treated as a root path.
  16. // This allows you to leverage the component nesting without having to use a nested URL.
  17. if (!(menu.path.startsWith('/') || isUrl(menu.path))) {
  18. // path doesn't start with /, nor is it a url, join parent path
  19. menu.path = `${parentPath}/${menu.path}`;
  20. }
  21. if (menu?.children?.length) {
  22. joinParentPath(menu.children, menu.meta?.hidePathForChildren ? parentPath : menu.path);
  23. }
  24. }
  25. }
  26. // Parsing the menu module
  27. export function transformMenuModule(menuModule: MenuModule): Menu {
  28. const { menu } = menuModule;
  29. const menuList = [menu];
  30. joinParentPath(menuList);
  31. return menuList[0];
  32. }
  33. export function transformRouteToMenu(routeModuleList: AppRouteModule[], routerMapping = false, parentPath = '') {
  34. const routeList: AppRouteRecordRaw[] = [];
  35. routeModuleList.forEach((node) => {
  36. if (node.meta.hideMenu) {
  37. return;
  38. }
  39. const item = {
  40. ...(node.meta || {}),
  41. meta: node.meta,
  42. name: node.meta.title,
  43. path: node.path,
  44. url: node.url,
  45. target: node.target,
  46. ...(node.redirect ? { redirect: node.redirect } : {}),
  47. children: node.children || [],
  48. };
  49. if (item.children) {
  50. item.children = transformRouteToMenu(
  51. item.children,
  52. routerMapping,
  53. item.meta?.hidePathForChildren ? parentPath : item.path,
  54. );
  55. }
  56. if (routerMapping && item.meta.hideChildrenInMenu && typeof item.redirect === 'string') {
  57. item.path = item.redirect;
  58. }
  59. // https://next.router.vuejs.org/guide/essentials/nested-routes.html
  60. // Note that nested paths that start with / will be treated as a root path.
  61. // This allows you to leverage the component nesting without having to use a nested URL.
  62. // if (!(item.path.startsWith('/') || isUrl(item.path))) {
  63. // // path doesn't start with /, nor is it a url, join parent path
  64. // item.path = `${parentPath}/${item.path}`;
  65. // }
  66. if (item.meta?.single) {
  67. const realItem = item?.children?.[0];
  68. realItem && routeList.push(realItem);
  69. } else {
  70. routeList.push(item);
  71. }
  72. });
  73. return routeList;
  74. }
  75. /**
  76. * config menu with given params
  77. */
  78. const menuParamRegex = /(?::)([\s\S]+?)((?=\/)|$)/g;
  79. export function configureDynamicParamsMenu(menu: Menu, params: RouteParams) {
  80. const { path, paramPath } = toRaw(menu);
  81. let realPath = paramPath ? paramPath : path;
  82. const matchArr = realPath.match(menuParamRegex);
  83. matchArr?.forEach((it) => {
  84. const realIt = it.substr(1);
  85. if (params[realIt]) {
  86. realPath = realPath.replace(`:${realIt}`, params[realIt] as string);
  87. }
  88. });
  89. // save original param path.
  90. if (!paramPath && matchArr && matchArr.length > 0) {
  91. menu.paramPath = path;
  92. }
  93. menu.path = realPath;
  94. // children
  95. menu.children?.forEach((item) => configureDynamicParamsMenu(item, params));
  96. }