一般我们“菜单“保存在数据库时,不会仅仅保存路由相关参数,还会增加一下自定义参数,类似下面的数据结构:
const menu = {
id: "1",
pid: "-1", // 父id
nameCn: "平台管理", //中文名
type: "menu", //类别:menu 菜单,button 按钮
icon: "platform", //图标
routeName: "platform", //路由名
routePath: "/platform", //路由地址
routeLevel: 1, //路由级别: 一级路由(左侧显示) 二级路由(左侧不显示)
componentPath: "", //组件路径
sort: 1, //排序
children: [],
};
所以需要手动构造路由,渲染侧栏菜单
需要注意的地方:
效果图:
components/SvgIcon.vue
layout/index.vue
layout/components/MenuItem.vue
{{ menu.nameCn }}
{{ menu.nameCn }}
{{ menu.nameCn }}
router/index.ts
import { createRouter, createWebHistory } from "vue-router";
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: "/",
name: "index",
component: () => import("../layout/index.vue"),
meta: {
title: "index",
sort: 1,
},
},
],
// 刷新时,滚动条位置还原
scrollBehavior: () => ({ left: 0, top: 0 }),
});
export const menus = [
{
id: "1",
pid: "-1", // 父id
nameCn: "平台管理", //中文名
type: "menu", //类别:menu 菜单,button 按钮
icon: "platform", //图标
routeName: "platform", //路由名
routePath: "/platform", //路由地址
routeLevel: 1, //路由级别: 一级路由(左侧显示) 二级路由(左侧不显示)
componentPath: "", //组件路径
sort: 1, //排序
children: [
{
id: "1-1",
nameCn: "角色管理",
permission: "",
type: "menu",
pid: "1",
icon: "role",
iconColor: "",
routeName: "role",
routePath: "role",
routeLevel: 1,
componentPath: "/platform/role/index.vue",
sort: 1,
children: [
{
id: "1-1-1",
nameCn: "新增",
permission: "account:add",
type: "button",
pid: "1-1",
icon: "user",
iconColor: "",
routeName: "",
routePath: "",
routeLevel: null,
componentPath: "",
sort: 1,
children: [],
},
],
},
{
id: "1-2",
nameCn: "账户管理",
permission: "",
type: "menu",
pid: "1",
icon: "user",
iconColor: "",
routeName: "account",
routePath: "account",
routeLevel: 1,
componentPath: "/platform/account/index.vue",
sort: 2,
children: [],
},
],
},
{
id: "2",
pid: "-1",
nameCn: "资产管理",
type: "menu",
icon: "property",
routeName: "",
routePath: "/property",
routeLevel: 1,
componentPath: "",
sort: 2,
children: [
{
id: "2-1",
pid: "2",
nameCn: "文档管理",
permission: "",
type: "menu",
icon: "document",
iconColor: "",
routeName: "document",
routePath: "document",
routeLevel: 1,
componentPath: "/property/document/index.vue",
sort: 1,
children: [],
},
{
id: "2-2",
pid: "2",
nameCn: "硬件管理",
permission: null,
type: "menu",
icon: "hardware",
iconColor: "",
routeName: "",
routePath: "hardware",
routeLevel: 1,
componentPath: "/property/layout/Empty.vue",
sort: 2,
children: [
{
id: "2-2-1",
pid: "2-2",
nameCn: "硬件管理",
permission: null,
type: "menu",
icon: "",
routeName: "hardware",
routePath: "",
routeLevel: 2,
componentPath: "/property/hardware/index.vue",
sort: 1,
children: [],
},
{
id: "2-2-2",
pid: "2-2",
nameCn: "硬件配置",
permission: null,
type: "menu",
icon: "",
routeName: "config",
routePath: "config",
routeLevel: 2,
componentPath: "/property/hardware/Config.vue",
sort: 2,
children: [],
},
],
},
],
},
];
const initRouter = (routerTree: any) => {
const routerArr: any = [];
routerTree.forEach((item: any) => {
if (item.type === "menu") {
routerArr.push({
meta: { title: item.nameCn },
name: item.routeName || "",
path: item.routePath || "",
component: item.componentPath
? () => import(/* @vite-ignore */ "../view" + item.componentPath)
: "",
children: item.children ? initRouter(item.children) : [],
});
}
});
return routerArr;
};
const routers = initRouter(menus);
routers.forEach((item: any) => {
router.addRoute("index", item);
});
console.log(router.getRoutes());
export default router;
view/platform/account/index.vue
账户管理
view/platform/role/index.vue
角色管理
view/property/layout/Empty.vue
view/property/hardware/index.vue
硬件管理
硬件配置
view/property/hardware/Config.vue
硬件配置
view/property/document/index.vue
文档管理