feat: 重构菜单项生成逻辑,优化路由处理并支持分组结构
This commit is contained in:
@ -1,37 +1,75 @@
|
||||
<script setup lang="ts">
|
||||
import { createGetRoutes } from '@/plugins/router';
|
||||
import type { MenuItem } from 'primevue/menuitem';
|
||||
import type { PanelMenuProps } from 'primevue/panelmenu';
|
||||
|
||||
import type { RouteRecordRaw } from 'vue-router/auto';
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
// 递归处理路由生成菜单项
|
||||
const _generateMenuItems = (routes: RouteRecordRaw[]): PanelMenuProps['model'] => {
|
||||
return [];
|
||||
};
|
||||
|
||||
const cmptItems = computed(() => {
|
||||
return createGetRoutes(router)()
|
||||
const menuItems = computed(() => {
|
||||
let flatArray: MenuItem[] = createGetRoutes(router)()
|
||||
.filter((route) => !route.path.includes('/:'))
|
||||
.map((route, index) => {
|
||||
return {
|
||||
label: `${index}. ${(route.name as string) || route.path}`,
|
||||
icon: (route.meta?.icon as string) || 'pi pi-fw pi-home',
|
||||
// url: route.path,
|
||||
command: route.children?.length
|
||||
? undefined
|
||||
: () => {
|
||||
router.push(route);
|
||||
},
|
||||
} satisfies MenuItem;
|
||||
.map((route) => ({
|
||||
id: route.path,
|
||||
label: `${(route.name as string) || route.path}`,
|
||||
}));
|
||||
|
||||
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: MenuItem[]): MenuItem[] {
|
||||
return tree.map((item) => {
|
||||
if (item.children.length) {
|
||||
item.items = _convertChildrenToItems(item.children);
|
||||
} else {
|
||||
item.command = (event) => {
|
||||
router.push({ name: item.label as never });
|
||||
};
|
||||
}
|
||||
delete item.children;
|
||||
return item;
|
||||
});
|
||||
}
|
||||
return _convertChildrenToItems(tree);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<PanelMenu :model="cmptItems" />
|
||||
<PanelMenu :model="menuItems" />
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
@ -4,69 +4,6 @@ import type { MenuItem } from 'primevue/menuitem';
|
||||
import { routes } from 'vue-router/auto-routes';
|
||||
const router = useRouter();
|
||||
|
||||
const menuItems = computed(() => {
|
||||
let flatArray: MenuItem[] = createGetRoutes(router)()
|
||||
.filter((route) => !route.path.includes('/:'))
|
||||
.map((route) => ({
|
||||
id: route.path,
|
||||
label: `${(route.name as string) || route.path}`,
|
||||
}));
|
||||
|
||||
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: MenuItem[]): MenuItem[] {
|
||||
return tree.map((item) => {
|
||||
if (item.children.length) {
|
||||
item.items = _convertChildrenToItems(item.children);
|
||||
} else {
|
||||
item.command = (event) => {
|
||||
router.push({ name: item.label as never });
|
||||
};
|
||||
}
|
||||
delete item.children;
|
||||
return item;
|
||||
});
|
||||
}
|
||||
return _convertChildrenToItems(tree);
|
||||
});
|
||||
|
||||
const list = [
|
||||
{
|
||||
title: 'routes',
|
||||
@ -98,22 +35,14 @@ const list = [
|
||||
components: undefined,
|
||||
})),
|
||||
},
|
||||
{
|
||||
title: 'menuItems',
|
||||
json: menuItems.value,
|
||||
},
|
||||
];
|
||||
</script>
|
||||
<template>
|
||||
<Tabs value="MenuTest" scrollable>
|
||||
<Tabs :value="list[0].title" scrollable>
|
||||
<TabList>
|
||||
<Tab value="MenuTest"> MenuTest </Tab>
|
||||
<Tab v-for="item in list" :key="item.title" :value="item.title">{{ item.title }}</Tab>
|
||||
</TabList>
|
||||
<TabPanels>
|
||||
<TabPanel value="MenuTest">
|
||||
<PanelMenu :model="menuItems" />
|
||||
</TabPanel>
|
||||
<TabPanel v-for="item in list" :key="item.title" :value="item.title">
|
||||
<pre>{{ item.json }}</pre>
|
||||
</TabPanel>
|
||||
|
Reference in New Issue
Block a user