refactor(useMetaLayoutsMenuOptions): 优化路由过滤与排序逻辑
All checks were successful
CI/CD Pipeline / playwright (push) Successful in 4m9s
CI/CD Pipeline / build-and-deploy (push) Successful in 4m27s

This commit is contained in:
严浩
2025-10-27 14:04:58 +08:00
parent 267bf75bc1
commit d4d9620db2

View File

@@ -48,62 +48,68 @@ export function useMetaLayoutsNMenuOptions({ menuInstRef }: { menuInstRef: Ref<M
const menuMap = new Map<string, MenuOption>(); const menuMap = new Map<string, MenuOption>();
const rootMenus: MenuOption[] = []; const rootMenus: MenuOption[] = [];
// 过滤和排序路由 // 过滤路由
const validRoutes = routes const validRoutes = routes.filter((route) => {
.filter((route) => { // 过滤掉不需要显示的路由
// 过滤掉不需要显示的路由 if (route.meta?.hideInMenu === true || route.meta?.layout === false) {
if (route.meta?.hideInMenu === true || route.meta?.layout === false) { return false;
return false; }
} // 过滤掉通配符路径
// 过滤掉通配符路径 if (route.path.includes('*')) {
if (route.path.includes('*')) { return false;
return false; }
} // 根据环境变量判断是否显示 /demos 开头的路由
// 根据环境变量判断是否显示 /demos 开头的路由 if (import.meta.env.VITE_MENU_SHOW_DEMOS !== 'true' && route.path.startsWith('/demos')) {
if (import.meta.env.VITE_MENU_SHOW_DEMOS !== 'true' && route.path.startsWith('/demos')) { return false;
return false; }
} return true;
return true; });
})
// 排序路由,确保父路由总是在子路由之前,同级路由则根据 `meta.order` 排序
.sort((a: RouteRecordRaw, b: RouteRecordRaw) => {
const pathA = a.path;
const pathB = b.path;
const segmentsA = pathA.split('/').filter(Boolean);
const segmentsB = pathB.split('/').filter(Boolean);
const parentAPath = `/${segmentsA.slice(0, -1).join('/')}`;
const parentBPath = `/${segmentsB.slice(0, -1).join('/')}`;
// 如果不是同级路由,则按路径排序,确保父路由在前 // 排序路由:先按路径深度分组,再按 order 排序
if (parentAPath !== parentBPath) { const sortedRoutes = validRoutes.slice().sort((a: RouteRecordRaw, b: RouteRecordRaw) => {
return pathA.localeCompare(pathB); const pathA = a.path;
} const pathB = b.path;
// 同级路由,处理 `meta.order` // 1. 首先按路径深度排序(确保父路由在子路由之前)
const orderA = a.meta?.order; const depthA = pathA.split('/').filter(Boolean).length;
const orderB = b.meta?.order; const depthB = pathB.split('/').filter(Boolean).length;
const hasOrderA = orderA !== undefined; if (depthA !== depthB) {
const hasOrderB = orderB !== undefined; return depthA - depthB;
}
// 当一个有 order 而另一个没有时,有 order 的排在前面 // 2. 获取父路径,判断是否为同一父级下的路由
if (hasOrderA !== hasOrderB) { const segmentsA = pathA.split('/').filter(Boolean);
return hasOrderA ? -1 : 1; const segmentsB = pathB.split('/').filter(Boolean);
} const parentA = segmentsA.length > 1 ? `/${segmentsA.slice(0, -1).join('/')}` : '/';
const parentB = segmentsB.length > 1 ? `/${segmentsB.slice(0, -1).join('/')}` : '/';
// 当两个都有 order 时,按 order 值升序排序 // 如果父路径不同,按父路径字母顺序排序
if (hasOrderA && hasOrderB) { if (parentA !== parentB) {
const orderDiff = orderA - orderB; return parentA.localeCompare(parentB);
if (orderDiff !== 0) { }
return orderDiff;
}
}
// order 相同或都没有 order按路径字母顺序排序 // 3. 同一父级下的路由,按 order 排序
return pathA.localeCompare(pathB); const orderA = a.meta?.order;
}); const orderB = b.meta?.order;
const hasOrderA = typeof orderA === 'number';
const hasOrderB = typeof orderB === 'number';
// 有 order 的排在没有 order 的前面
if (hasOrderA && !hasOrderB) return -1;
if (!hasOrderA && hasOrderB) return 1;
// 都有 order 时,按 order 数值升序排序
if (hasOrderA && hasOrderB) {
const diff = (orderA as number) - (orderB as number);
if (diff !== 0) return diff;
}
// order 相同或都没有 order按路径名字母顺序排序
return pathA.localeCompare(pathB);
});
// 构建菜单树 // 构建菜单树
for (const route of validRoutes) { for (const route of sortedRoutes) {
const pathSegments = route.path.split('/').filter(Boolean); const pathSegments = route.path.split('/').filter(Boolean);
const routeName = route.name as string; const routeName = route.name as string;
@@ -147,30 +153,32 @@ export function useMetaLayoutsNMenuOptions({ menuInstRef }: { menuInstRef: Ref<M
} }
} }
// 添加调试日志
if (import.meta.env.DEV) {
console.debug(
'排序后的路由:',
sortedRoutes.map((route) => ({
path: route.path,
name: route.name,
order: route.meta?.order,
})),
);
}
return rootMenus; return rootMenus;
} }
// console.debug( if (import.meta.env.DEV) {
// '原始路由:', console.debug(
// JSON.stringify( '原始路由:',
// routes.map((route) => ({ routes.map((route) => ({
// // path path: route.path,
// // name name: route.name,
// // meta order: route.meta?.order,
// ...route, })),
// props: undefined, );
// children: undefined, console.debug('转换后的菜单:', options.value);
// instances: undefined, }
// leaveGuards: undefined,
// updateGuards: undefined,
// enterCallbacks: undefined,
// components: undefined,
// })),
// null,
// 0,
// ),
// );
// console.debug('转换后的菜单:', JSON.stringify(options.value, null, 0));
return { return {
options, options,