# 前端路由与菜单 前端路由定义页面的访问路径,菜单是路由的可视化展示。项目的路由和菜单由后端动态返回,前端只需注册路由组件映射。 ## 动态路由机制 项目的路由和菜单是动态的,由后端驱动: ``` 登录成功 → 请求 /index/getMenus → 生成动态路由 → 注册到 Vue Router → 渲染菜单 ``` ### 路由生成流程 1. 用户登录成功,获取 JWT Token 2. 前端路由守卫(`router-guards.ts`)检测到已登录 3. 调用 `GET /index/getMenus` 获取菜单树 4. 将菜单树转换为 Vue Router 路由记录 5. 使用 `router.addRoute()` 动态注册路由 6. 渲染侧边栏菜单 ### 关键代码 ```typescript // 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` 文件: ```typescript // 扫描 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` 返回的菜单数据: ```json { "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 | 对应一个操作权限,不在菜单中显示 | ## 开发要点 1. **路由和菜单由后端动态返回**:前端不需要手动编辑路由文件 2. **component 字段必须与 .vue 文件路径对应**:否则页面白屏 3. **使用 `import.meta.glob` 自动扫描组件**:无需手动注册 4. **菜单类型区分目录和权限**:目录用于分组,权限用于按钮控制 5. **新增模块只需在菜单管理中配置**:自动出现在前端菜单中 ## 总结 前端路由使用 Vue Router 4,菜单路由由后端动态返回,前端通过 `addRoute` 动态注册。路由守卫负责权限校验和登录状态检查,未登录自动跳转登录页。新增模块只需在菜单管理中配置,无需编辑前端路由文件。