routeHelper.ts
4.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import type { AppRouteModule, AppRouteRecordRaw } from '/@/router/types';
import type { Router, RouteRecordNormalized } from 'vue-router';
import { getParentLayout, LAYOUT } from '/@/router/constant';
import { cloneDeep } from 'lodash-es';
import { warn } from '/@/utils/log';
import { createRouter, createWebHashHistory } from 'vue-router';
export type LayoutMapKey = 'LAYOUT';
const LayoutMap = new Map<LayoutMapKey, () => Promise<typeof import('*.vue')>>();
let dynamicViewsModules: Record<string, () => Promise<Recordable>>;
// Dynamic introduction
function asyncImportRoute(routes: AppRouteRecordRaw[] | undefined) {
dynamicViewsModules = dynamicViewsModules || import.meta.glob('../../views/**/*.{vue,tsx}');
if (!routes) return;
routes.forEach((item) => {
const { component, name } = item;
const { children } = item;
if (component) {
item.component = dynamicImport(dynamicViewsModules, component as string);
} else if (name) {
item.component = getParentLayout();
}
children && asyncImportRoute(children);
});
}
function dynamicImport(
dynamicViewsModules: Record<string, () => Promise<Recordable>>,
component: string
) {
const keys = Object.keys(dynamicViewsModules);
const matchKeys = keys.filter((key) => {
let k = key.replace('../../views', '');
const lastIndex = k.lastIndexOf('.');
k = k.substring(0, lastIndex);
return k === component;
});
if (matchKeys?.length === 1) {
const matchKey = matchKeys[0];
return dynamicViewsModules[matchKey];
}
if (matchKeys?.length > 1) {
warn(
'Please do not create `.vue` and `.TSX` files with the same file name in the same hierarchical directory under the views folder. This will cause dynamic introduction failure'
);
return;
}
}
// Turn background objects into routing objects
export function transformObjToRoute<T = AppRouteModule>(routeList: AppRouteModule[]): T[] {
LayoutMap.set('LAYOUT', LAYOUT);
routeList.forEach((route) => {
if (route.component) {
if ((route.component as string).toUpperCase() === 'LAYOUT') {
//route.component = LayoutMap.get(route.component as LayoutMapKey);
route.component = LayoutMap.get((route.component as string).toUpperCase() as LayoutMapKey);
} else {
route.children = [cloneDeep(route)];
route.component = LAYOUT;
route.name = `${route.name}Parent`;
route.path = '';
const meta = route.meta || {};
meta.single = true;
meta.affix = false;
route.meta = meta;
}
}
route.children && asyncImportRoute(route.children);
});
return (routeList as unknown) as T[];
}
/**
* Convert multi-level routing to level 2 routing
*/
export function flatRoutes(routeModules: AppRouteModule[]) {
for (let index = 0; index < routeModules.length; index++) {
const routeModule = routeModules[index];
if (!isMultipleRoute(routeModule)) {
continue;
}
promoteRouteLevel(routeModule);
}
}
// Routing level upgrade
function promoteRouteLevel(routeModule: AppRouteModule) {
// Use vue-router to splice menus
let router: Router | null = createRouter({
routes: [routeModule as any],
history: createWebHashHistory(),
});
const routes = router.getRoutes();
const children = cloneDeep(routeModule.children);
addToChildren(routes, children || [], routeModule);
router = null;
routeModule.children = routeModule.children?.filter((item) => !item.children?.length);
}
// Add all sub-routes to the secondary route
function addToChildren(
routes: RouteRecordNormalized[],
children: AppRouteRecordRaw[],
routeModule: AppRouteModule
) {
for (let index = 0; index < children.length; index++) {
const child = children[index];
const route = routes.find((item) => item.name === child.name);
if (route) {
routeModule.children = routeModule.children || [];
routeModule.children?.push(route as any);
if (child.children?.length) {
addToChildren(routes, child.children, routeModule);
}
}
}
}
// Determine whether the level exceeds 2 levels
function isMultipleRoute(routeModule: AppRouteModule) {
if (!routeModule || !Reflect.has(routeModule, 'children') || !routeModule.children?.length) {
return false;
}
const children = routeModule.children;
let flag = false;
for (let index = 0; index < children.length; index++) {
const child = children[index];
if (child.children?.length) {
flag = true;
break;
}
}
return flag;
}