Files
vue-ts-example/src/layouts/sakai-vue/AppMenu.vue
mini2024 8733c3e42e
All checks were successful
/ depcheck (push) Successful in 2m3s
/ build-and-deploy-to-vercel (push) Successful in 2m59s
/ surge (push) Successful in 3m27s
/ playwright (push) Successful in 2m48s
chore(deps): 升级 oxlint
2025-03-09 23:30:29 +08:00

80 lines
2.2 KiB
Vue

<script setup lang="ts">
import type { MenuItem } from 'primevue/menuitem';
import { createGetRoutes } from '@/plugins/router';
const router = useRouter();
type MenuItemWithRoute = MenuItem & { routeName?: string };
const menuItems = computed(() => {
let flatArray: MenuItemWithRoute[] = createGetRoutes(router)()
.filter((route) => !route.path.includes('/:'))
.filter((route) => !route.meta.hidden)
.map((route) => ({
id: route.path,
label: route.meta.title || `${(route.name as string) || route.path}`,
routeName: route.name as string,
}));
flatArray = flatArray.map((item /* index */) => {
let id = item.id;
if (flatArray.some((item) => item.id.startsWith(`${id}/`))) {
id = `${id}/index`;
}
// 去掉最前面的 /
id = id.replace(/^\//, '');
let parentId = id.replace(/\/[^/]+$/, '');
if (parentId === id) {
parentId = '_ROOT_';
}
return {
...item,
parentId,
};
});
const groupItems = flatArray.reduce(
(acc, flatArrItem) => {
if (
!acc.some((item) => item.id === flatArrItem.parentId) && //
flatArrItem.parentId !== '_ROOT_'
) {
let groupItemParentId = flatArrItem.parentId.replace(/\/[^/]+$/, '');
if (groupItemParentId === flatArrItem.parentId) groupItemParentId = '_ROOT_';
acc.push({
id: flatArrItem.parentId,
label: `Group ${flatArrItem.parentId}`,
parentId: groupItemParentId,
});
}
return acc;
},
[] as Record<string, string>[],
);
console.debug(`groupItems :>> `, groupItems);
const tree = arrayToTree(flatArray.concat(groupItems), { id: 'id', parentId: 'parentId', rootId: '_ROOT_' });
// 递归把 children 改为 items
function _convertChildrenToItems(tree: MenuItemWithRoute[]) {
return tree.map((item) => {
if (item.children.length) {
item.items = _convertChildrenToItems(item.children);
} else {
item.command = (/* event */) => {
router.push({ name: item.routeName as never });
};
}
delete item.children;
return item;
});
}
return _convertChildrenToItems(tree);
});
</script>
<template>
<PanelMenu :model="menuItems" />
</template>
<style lang="scss" scoped></style>