Files
lingji-work-fe/src/components/_base/menu/use-menu-tree.ts

61 lines
1.7 KiB
TypeScript
Raw Normal View History

2025-06-16 14:42:26 +08:00
import type { RouteRecordRaw, RouteRecordNormalized } from 'vue-router';
import { useAppStore } from '@/stores';
import appClientMenus from '@/router/app-menus';
export default function useMenuTree() {
const appStore = useAppStore();
const appRoute = computed(() => {
if (appStore.menuFromServer) {
// return appClientMenus.concat(toRaw(appStore.appAsyncMenus));
return toRaw(appStore.appAsyncMenus);
}
return appClientMenus;
});
const menuTree = computed(() => {
const copyRouter = cloneDeep(appRoute.value) as RouteRecordNormalized[];
copyRouter.sort((a: RouteRecordNormalized, b: RouteRecordNormalized) => {
return (a.meta.order || 0) - (b.meta.order || 0);
});
function travel(_routes: RouteRecordRaw[], layer: number) {
if (!_routes) return null;
const collector: any = _routes.map((element) => {
// leaf node
if (element.meta?.hideChildrenInMenu || !element.children) {
element.children = [];
return element;
}
// route filter hideInMenu true
element.children = element.children.filter((x) => x.meta?.hideInMenu !== true);
// Associated child node
const subItem = travel(element.children, layer + 1);
if (subItem.length) {
element.children = subItem;
return element;
}
// the else logic
if (layer > 1) {
element.children = subItem;
return element;
}
if (element.meta?.hideInMenu === false) {
return element;
}
return null;
});
return collector.filter(Boolean);
}
return travel(copyRouter, 0);
});
return {
menuTree,
};
}