Skip to content

前端路由与菜单

前端路由定义页面的访问路径,菜单是路由的可视化展示。项目的路由和菜单由后端动态返回,前端只需注册路由组件映射。

动态路由机制

项目的路由和菜单是动态的,由后端驱动:

登录成功 → 请求 /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/indexui/src/views/tool/example/index.vue
system/user/indexui/src/views/system/user/index.vue
content/article/indexui/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 动态注册。路由守卫负责权限校验和登录状态检查,未登录自动跳转登录页。新增模块只需在菜单管理中配置,无需编辑前端路由文件。

小蚂蚁云团队 · 提供技术支持