feat(router): 优化路由排序逻辑并添加菜单排序权重支持
This commit is contained in:
@@ -44,7 +44,42 @@ function convertRoutesToMenuOptions(routes: Readonly<RouteRecordRaw[]>): MenuOpt
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.sort((a, b) => a.path.localeCompare(b.path));
|
// 排序路由,确保父路由总是在子路由之前,同级路由则根据 `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('/')}`;
|
||||||
|
|
||||||
|
// 如果不是同级路由,则按路径排序,确保父路由在前
|
||||||
|
if (parentAPath !== parentBPath) {
|
||||||
|
return pathA.localeCompare(pathB);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 同级路由,处理 `meta.order`
|
||||||
|
const orderA = a.meta?.order;
|
||||||
|
const orderB = b.meta?.order;
|
||||||
|
const hasOrderA = orderA !== undefined;
|
||||||
|
const hasOrderB = orderB !== undefined;
|
||||||
|
|
||||||
|
// 当一个有 order 而另一个没有时,有 order 的排在前面
|
||||||
|
if (hasOrderA !== hasOrderB) {
|
||||||
|
return hasOrderA ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当两个都有 order 时,按 order 值升序排序
|
||||||
|
if (hasOrderA && hasOrderB) {
|
||||||
|
const orderDiff = orderA - orderB;
|
||||||
|
if (orderDiff !== 0) {
|
||||||
|
return orderDiff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// order 相同或都没有 order,按路径字母顺序排序
|
||||||
|
return pathA.localeCompare(pathB);
|
||||||
|
});
|
||||||
|
|
||||||
// 构建菜单树
|
// 构建菜单树
|
||||||
for (const route of validRoutes) {
|
for (const route of validRoutes) {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
definePage({
|
definePage({
|
||||||
meta: {},
|
meta: {
|
||||||
|
order: 1,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
const { t, locale } = useI18n();
|
const { t, locale } = useI18n();
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
definePage({ meta: { link: !false } });
|
definePage({
|
||||||
|
meta: {
|
||||||
|
link: !false,
|
||||||
|
},
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<template><div>Demos</div></template>
|
<template><div>Demos</div></template>
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
import { autoAnimatePlugin } from '@formkit/auto-animate/vue';
|
|
||||||
|
|
||||||
export function install({ app }: { app: import('vue').App<Element> }) {
|
export function install({ app }: { app: import('vue').App<Element> }) {
|
||||||
app.config.globalProperties.__DEV__ = __DEV__;
|
app.config.globalProperties.__DEV__ = __DEV__;
|
||||||
|
|
||||||
app.use(autoAnimatePlugin); // v-auto-animate="{ duration: 100 }"
|
|
||||||
|
|
||||||
app.config.errorHandler = (error, instance, info) => {
|
app.config.errorHandler = (error, instance, info) => {
|
||||||
console.error('Global error:', error);
|
console.error('Global error:', error);
|
||||||
console.error('Component:', instance);
|
console.error('Component:', instance);
|
||||||
|
|||||||
@@ -43,8 +43,10 @@ declare module 'vue-router' {
|
|||||||
* @description 是否在菜单中隐藏
|
* @description 是否在菜单中隐藏
|
||||||
*/
|
*/
|
||||||
hideInMenu?: boolean;
|
hideInMenu?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 菜单标题
|
* @description 菜单标题
|
||||||
|
* @deprecated //!⚠️请通过多语言标题方案(搜`PageTitleLocalizations`)维护标题
|
||||||
*/
|
*/
|
||||||
title?: string;
|
title?: string;
|
||||||
|
|
||||||
@@ -59,6 +61,11 @@ declare module 'vue-router' {
|
|||||||
* - false: 仅渲染纯文本标签,不可点击(适用于分组标题)
|
* - false: 仅渲染纯文本标签,不可点击(适用于分组标题)
|
||||||
*/
|
*/
|
||||||
link?: boolean;
|
link?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 菜单排序权重,数值越小越靠前,未设置则按路径字母顺序排序
|
||||||
|
*/
|
||||||
|
order?: number;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user