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
|
export function createRouteMap(
routes: Array<RouteConfig>,
oldPathList?: Array<string>,
oldPathMap?: Dictionary<RouteRecord>,
oldNameMap?: Dictionary<RouteRecord>
) {
// 用来控制路径匹配优先级
const pathList: Array<string> = oldPathList || [];
const pathMap: Dictionary<RouteRecord> = oldPathMap || Object.create(null);
const nameMap: Dictionary<RouteRecord> = oldNameMap || Object.create(null);
routes.forEach(route => {
addRouteRecord(pathList, pathMap, nameMap, route);
});
// 确保 path 为通配符的路由一直在结尾
for (let i = 0, l = pathList.length; i < l; i++) {
if (pathList[i] === '*') {
pathList.push(pathList.splice(i, 1)[0]);
l--;
i--;
}
}
return {
pathList, // routePath[]
pathMap, // {path: record, ...}
nameMap // {name: rocord, ...}
};
}
function addRouteRecord(
pathList: Array<string>,
pathMap: Dictionary<RouteRecord>,
nameMap: Dictionary<RouteRecord>,
route: RouteConfig,
parent?: RouteRecord,
matchAs?: string
) {
const { path, name } = route;
// 去除 path 最后的 /,并拼接上 parent.path
const normalizedPath = normalizePath(path, parent);
const pathToRegexpOptions: PathToRegexpOptions =
route.pathToRegexpOptions || {};
if (typeof route.caseSensitive === 'boolean') {
pathToRegexpOptions.sensitive = route.caseSensitive;
}
// 根据传入的 route 生成一个 record
const record: RouteRecord = {
path: normalizedPath, // 规范化之后的 path,带上父级路由的那种
regex: compileRouteRegex(normalizedPath, pathToRegexpOptions), // 将 path 解析成正则表达式
// 一条 path 可以对应多个 components,通过 router-view 的 name 属性来判断渲染出口
components: route.components || { default: route.component },
instances: {},
name,
parent, // ParentRouteRecord
matchAs,
redirect: route.redirect,
beforeEnter: route.beforeEnter,
meta: route.meta || {},
props:
route.props == null
? {}
: route.components
? route.props
: { default: route.props }
};
if (route.children) {
console.warn(
'如果 route 有 name,没有重定向,有一个默认的子路由,如果通过 name 进行导航,默认的子路由不会渲染'
);
route.children.forEach(child => {
const childMatchAs = matchAs
? cleanPath(`${matchAs}/${child.path}`)
: undefined;
// record 作为 children 的 parent,重新调用 addRouteRecord
addRouteRecord(pathList, pathMap, nameMap, child, record, childMatchAs);
});
}
// 如果路由有别名,同样会生成一条 record
if (route.alias !== undefined) {
const aliases = Array.isArray(route.alias) ? route.alias : [route.alias];
aliases.forEach(alias => {
const aliasRoute = {
path: alias,
children: route.children
};
addRouteRecord(
pathList,
pathMap,
nameMap,
aliasRoute,
parent,
record.path || '/' // matchAs
);
});
}
if (!pathMap[record.path]) {
pathList.push(record.path);
pathMap[record.path] = record;
}
if (name) {
if (!nameMap[name]) {
nameMap[name] = record;
}
}
}
|