admin-vben5/packages/utils/src/helpers/generate-menus.ts

82 lines
2.2 KiB
TypeScript
Raw Normal View History

import type { Router, RouteRecordRaw } from 'vue-router';
2024-06-02 15:04:37 +08:00
import type { ExRouteRecordRaw, MenuRecordRaw } from '@vben-core/typings';
import { filterTree, mapTree } from '@vben-core/shared/utils';
2024-06-02 15:04:37 +08:00
/**
* routes
* @param routes
*/
async function generateMenus(
2024-06-02 15:04:37 +08:00
routes: RouteRecordRaw[],
router: Router,
): Promise<MenuRecordRaw[]> {
// 将路由列表转换为一个以 name 为键的对象映射
// 获取所有router最终的path及name
const finalRoutesMap: { [key: string]: string } = Object.fromEntries(
router.getRoutes().map(({ name, path }) => [name, path]),
);
let menus = mapTree<ExRouteRecordRaw, MenuRecordRaw>(routes, (route) => {
2024-06-02 15:04:37 +08:00
// 路由表的路径写法有多种这里从router获取到最终的path并赋值
const path = finalRoutesMap[route.name as string] ?? route.path;
// 转换为菜单结构
// const path = matchRoute?.path ?? route.path;
const { meta, name: routeName, redirect, children } = route;
const {
activeIcon,
2024-06-02 15:04:37 +08:00
badge,
badgeType,
badgeVariants,
hideChildrenInMenu = false,
icon,
2024-06-08 20:14:04 +08:00
link,
2024-06-02 23:46:18 +08:00
order,
2024-06-02 15:04:37 +08:00
title = '',
} = meta || {};
const name = (title || routeName || '') as string;
// 隐藏子菜单
const resultChildren = hideChildrenInMenu
? []
: (children as MenuRecordRaw[]);
// 将菜单的所有父级和父级菜单记录到菜单项内
if (resultChildren && resultChildren.length > 0) {
resultChildren.forEach((child) => {
child.parents = [...(route.parents || []), path];
child.parent = path;
});
}
// 隐藏子菜单
2024-06-08 20:14:04 +08:00
const resultPath = hideChildrenInMenu ? redirect || path : link || path;
2024-06-02 15:04:37 +08:00
return {
activeIcon,
2024-06-02 15:04:37 +08:00
badge,
badgeType,
badgeVariants,
icon,
name,
2024-06-02 23:46:18 +08:00
order,
2024-06-02 15:04:37 +08:00
parent: route.parent,
parents: route.parents,
path: resultPath as string,
show: !route?.meta?.hideInMenu,
2024-06-02 15:04:37 +08:00
children: resultChildren || [],
};
});
// 对菜单进行排序
2024-06-02 23:46:18 +08:00
menus = menus.sort((a, b) => (a.order || 999) - (b.order || 999));
const finalMenus = filterTree(menus, (menu) => {
return !!menu.show;
});
return finalMenus;
2024-06-02 15:04:37 +08:00
}
export { generateMenus };