Vue实战@根据路由生成菜单

概述

整体思路就是在每个路由下面增加 meta 属性维护需要在菜单显示的数据,例如meta: { icon: "dashboard", title: "仪表盘" },以及加些标志位区分需要过滤掉的路由,然后遍历routes获取相关数据,最后页面渲染显示。配套测试源码

详述

路由配置参考

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
const router = new Router({
mode: "history",
base: process.env.BASE_URL,
routes: [
{
path: "/user",
hideInMenu: true,
component: () =>
import(/* webpackChunkName: "user" */ "./layouts/UserLayout.vue"),
children: [
{
path: "/user",
redirect: "/user/login"
},
{
path: "/user/login",
name: "login",
component: () =>
import(/* webpackChunkName: "user" */ "./views/User/Login.vue")
},
{
path: "/user/register",
name: "register",
component: () =>
import(/* webpackChunkName: "user" */ "./views/User/Register.vue")
}
]
},
{
path: "/",
meta: { authority: ["user", "admin"] },
component: () =>
import(/* webpackChunkName: "basic" */ "./layouts/BasicLayout.vue"),
children: [
{
path: "/",
redirect: "/dashboard/analysis"
},
// dashboard
{
path: "/dashboard",
name: "dashboard",
meta: { icon: "dashboard", title: "仪表盘" },
component: { render: h => h("router-view") },
children: [
{
path: "/dashboard/analysis",
name: "analysis",
meta: { title: "分析页" },
component: () =>
import(
/* webpackChunkName: "dashboard" */ "./views/Dashboard/Analysis.vue"
)
}
]
},
// form
{
path: "/form",
name: "form",
meta: { icon: "form", title: "表单", authority: ["admin"] },
component: { render: h => h("router-view") },
children: [
{
path: "/form/basic-form",
name: "basic-form",
meta: { title: "基础表单" },
component: () =>
import(
/* webpackChunkName: "form" */ "./views/Forms/BasicForm.vue"
)
},
{
path: "/form/step-form",
name: "step-form",
hideChildrenInMenu: true,
meta: { title: "分布表单" },
component: () =>
import(
/* webpackChunkName: "form" */ "./views/Forms/StepForm.vue"
),
children: [
{
path: "/form/step-form",
redirect: "/form/step-form/info"
},
{
path: "/form/step-form/info",
name: "info",
component: () =>
import(
/* webpackChunkName: "form" */ "./views/Forms/StepForm/Step1"
)
},
{
path: "/form/step-form/confirm",
name: "confirm",
component: () =>
import(
/* webpackChunkName: "form" */ "./views/Forms/StepForm/Step2"
)
},
{
path: "/form/step-form/result",
name: "result",
component: () =>
import(
/* webpackChunkName: "form" */ "./views/Forms/StepForm/Step3"
)
}
]
}
]
}
]
},
{
path: "/403",
name: "403",
hideInMenu: true,
component: Fobidden
},
{
path: "*",
name: "404",
hideInMenu: true,
component: NotFound
}
]
});

提取菜单显示所需信息

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
getMenuData(routes = [], parentKeys = [], selectedKey) {
const menuData = [];
routes.forEach(element => {
if (element.name && !element.hideInMenu) {
this.openKeysMap[element.path] = parentKeys;
this.selectedKeysMap[element.path] = [selectedKey || element.path];
const newItem = { ...element };
delete newItem.children;
if (element.children && !element.hideChildrenInMenu) {
newItem.children = this.getMenuData(element.children, [
...parentKeys,
element.path
]);
} else {
this.getMenuData(
element.children,
selectedKey ? parentKeys : [...parentKeys, element.path],
selectedKey || element.path
);
}
menuData.push(newItem);
} else if (
!element.hideInMenu &&
!element.hideChildrenInMenu &&
element.children
) {
menuData.push(
...this.getMenuData(element.children, [...parentKeys, element.path])
);
}
});
return menuData;
}

参考

极客时间——Vue 开发实战