4.4 KiB
4.4 KiB
前端路由与菜单
前端路由定义页面的访问路径,菜单是路由的可视化展示。项目的路由和菜单由后端动态返回,前端只需注册路由组件映射。
动态路由机制
项目的路由和菜单是动态的,由后端驱动:
登录成功 → 请求 /index/getMenus → 生成动态路由 → 注册到 Vue Router → 渲染菜单
路由生成流程
- 用户登录成功,获取 JWT Token
- 前端路由守卫(
router-guards.ts)检测到已登录 - 调用
GET /index/getMenus获取菜单树 - 将菜单树转换为 Vue Router 路由记录
- 使用
router.addRoute()动态注册路由 - 渲染侧边栏菜单
关键代码
// src/router/generator-routers.ts
// 将后端菜单转换为前端路由
function generateRoutes(menus) {
const routes = [];
for (const menu of menus) {
const route = {
path: menu.path,
name: menu.name,
component: loadComponent(menu.component), // 动态加载组件
meta: {
title: menu.name,
icon: menu.icon,
},
};
if (menu.children) {
route.children = generateRoutes(menu.children);
}
routes.push(route);
}
return routes;
}
菜单 component 字段
后端菜单的 component 字段必须与前端 .vue 文件路径对应:
| 菜单 component | 前端文件路径 |
|---|---|
tool/example/index |
ui/src/views/tool/example/index.vue |
system/user/index |
ui/src/views/system/user/index.vue |
content/article/index |
ui/src/views/content/article/index.vue |
组件加载方式
前端使用 import.meta.glob 自动扫描所有 .vue 文件:
// 扫描 src/views/ 下所有 .vue 文件
const modules = import.meta.glob('../views/**/*.vue');
function loadComponent(component) {
const path = `../views/${component}.vue`;
return modules[path];
}
后端菜单配置
在「系统管理 -> 菜单管理」中添加菜单节点:
| 字段 | 值 | 说明 |
|---|---|---|
| 菜单名称 | 案例管理 | 菜单显示名称 |
| 菜单类型 | 菜单(type=0) | 目录/菜单/权限 |
| 路由路径 | /tool/example |
前端路由路径 |
| 组件路径 | tool/example/index |
对应 .vue 文件路径 |
| 菜单图标 | 选择合适图标 | 菜单图标 |
| 排序号 | 设置显示顺序 | 菜单排序 |
| 状态 | 启用 | 是否启用 |
菜单数据返回格式
后端接口 /index/getMenus 返回的菜单数据:
{
"code": 0,
"data": [
{
"id": 10,
"name": "系统工具",
"parent_id": 0,
"path": "/tool",
"component": "Layout",
"type": 0,
"icon": "tool",
"children": [
{
"id": 101,
"name": "案例管理",
"parent_id": 10,
"path": "/tool/example",
"component": "tool/example/index",
"type": 0,
"icon": "example"
}
]
}
]
}
菜单与权限的关系
菜单管理
├── 系统工具(目录,type=0)
│ ├── 案例管理(菜单,type=0)
│ │ ├── 案例查询(权限,type=1)→ sys:example:page
│ │ ├── 案例新增(权限,type=1)→ sys:example:add
│ │ ├── 案例编辑(权限,type=1)→ sys:example:update
│ │ ├── 案例删除(权限,type=1)→ sys:example:delete
│ │ └── 案例状态(权限,type=1)→ sys:example:status
│ └── ...
└── ...
| 节点类型 | type | 作用 |
|---|---|---|
| 目录 | 0 | 菜单分组,不对应页面 |
| 菜单 | 0 | 对应一个页面路由 |
| 权限 | 1 | 对应一个操作权限,不在菜单中显示 |
开发要点
- 路由和菜单由后端动态返回:前端不需要手动编辑路由文件
- component 字段必须与 .vue 文件路径对应:否则页面白屏
- 使用
import.meta.glob自动扫描组件:无需手动注册 - 菜单类型区分目录和权限:目录用于分组,权限用于按钮控制
- 新增模块只需在菜单管理中配置:自动出现在前端菜单中
总结
前端路由使用 Vue Router 4,菜单路由由后端动态返回,前端通过 addRoute 动态注册。路由守卫负责权限校验和登录状态检查,未登录自动跳转登录页。新增模块只需在菜单管理中配置,无需编辑前端路由文件。