菜单路由

前端项目基于 Vben Admin 5.x 实现,它已经内置了路由、菜单、权限等功能。

官方文档

强烈建议先阅读 Vben Admin 官方文档,了解框架的基础概念和使用方式:

1. 路由

项目的路由分为两种:静态路由、动态路由。

1.1 静态路由

静态路由,是指在前端代码中直接定义的路由,不依赖后端接口返回。适用于一些固定的页面,如首页、个人中心等。

静态路由文件位于 src/router/routes/modules 目录下:

路由模块 antd 版本 ele 版本
首页 dashboard.ts (opens new window) dashboard.ts (opens new window)
系统管理 system.ts (opens new window) system.ts (opens new window)
基础设施 infra.ts (opens new window) infra.ts (opens new window)
AI 大模型 ai.ts (opens new window) ai.ts (opens new window)
工作流程 bpm.ts (opens new window) bpm.ts (opens new window)
CRM 系统 crm.ts (opens new window) crm.ts (opens new window)
商城系统 mall.ts (opens new window) mall.ts (opens new window)
会员系统 member.ts (opens new window) member.ts (opens new window)
支付系统 pay.ts (opens new window) pay.ts (opens new window)

1.2 动态路由

动态路由,代表那些需要根据用户动态判断权限,并通过 addRoutes (opens new window) 动态添加的页面,如用户管理、角色管理等功能页面。

在用户登录成功后,会触发 @/store/auth.ts (opens new window)fetchUserInfo 方法,请求后端的菜单 RESTful API 接口,获取用户有权限的菜单列表,并存储到 accessStore 中。

之后,@/router/access.ts (opens new window)generateAccess 方法,会将菜单转化为路由并动态添加。

友情提示:

  1. 动态路由可以在 [系统管理 -> 菜单管理] 进行新增和修改操作,请求的后端 RESTful API 接口是 /admin-api/system/auth/get-permission-info (opens new window)
  2. 动态路由使用 import.meta.glob 实现路由懒加载,参考 @/router/access.ts (opens new window) 中的 pageMap 定义

1.3 路由跳转

使用 useRouterpush 方法,可以实现跳转到不同的页面。

import { useRouter } from 'vue-router';

const { push } = useRouter();

// 方式一:使用 path 跳转
push('/system/user');

// 方式二:使用 path 跳转,并设置 query 参数
push('/bpm/process-instance/detail?id=' + row.processInstance.id);

// 方式三(推荐):使用 name 跳转,并设置 query 参数
push({ name: 'BpmProcessInstanceDetail', query: { id: row.processInstance.id } });

推荐使用 name 方式跳转,因为 path 方式在路由路径变更时需要同步修改,而 name 方式更加稳定。

2. 菜单管理

项目的菜单在 [系统管理 -> 菜单管理] 进行管理,支持无限层级,提供目录、菜单、按钮三种类型。如下图所示:

系统管理 -> 菜单管理

菜单可在 [系统管理 -> 角色管理] 被分配给角色。如下图所示:

系统管理 -> 角色管理

2.1 新增目录

① 大多数情况下,目录是作为菜单的【分类】:

新增目录 —— 菜单的分类

② 目录也提供实现【外链】的能力:

新增目录 —— 外链

注意,默认会在【新窗口】打开外链接!如果希望通过 iframe 内嵌打开,则可以在外链拼接上 ?_iframe 参数即可。

2.2 新增菜单

新增菜单

注意,“路由地址”可以通过 ? 拼接查询参数 (opens new window),实现传递参数的功能。

2.3 新增按钮

新增按钮

3. 权限控制

前端通过权限控制,隐藏用户没有权限的按钮等,实现功能级别的权限。

友情提示:前端的权限控制,主要是提升用户体验,避免操作后发现没有权限。

最终在请求到后端时,还是会进行一次权限的校验。

更多可阅读 《权限》 (opens new window) 的「按钮细粒度控制」。


另外,项目的 TableAction 组件的 auth 属性,可进行按钮级别的权限控制。示例如下:

<template>
  <Grid table-title="岗位列表">
    <!-- 工具栏按钮 -->
    <template #toolbar-tools>
      <TableAction
        :actions="[
          {
            label: $t('ui.actionTitle.create', ['岗位']),
            type: 'primary',
            icon: ACTION_ICON.ADD,
            auth: ['system:post:create'],
            onClick: handleCreate,
          },
          {
            label: $t('ui.actionTitle.export'),
            type: 'primary',
            icon: ACTION_ICON.DOWNLOAD,
            auth: ['system:post:export'],
            onClick: handleExport,
          },
        ]"
      />
    </template>
    <!-- 行操作按钮 -->
    <template #actions="{ row }">
      <TableAction
        :actions="[
          {
            label: $t('common.edit'),
            type: 'link',
            icon: ACTION_ICON.EDIT,
            auth: ['system:post:update'],
            onClick: handleEdit.bind(null, row),
          },
          {
            label: $t('common.delete'),
            type: 'link',
            danger: true,
            icon: ACTION_ICON.DELETE,
            auth: ['system:post:delete'],
            popConfirm: {
              title: $t('ui.actionMessage.deleteConfirm', [row.name]),
              confirm: handleDelete.bind(null, row),
            },
          },
        ]"
      />
    </template>
  </Grid>
</template>

4. 页面缓存

开启缓存时,需要将 keepAlive 设置为 true,如下所示:

友情提示:页面缓存是什么?

简单来说,Tab 切换时,开启页面缓存的 Tab 保持原本的状态,不进行刷新。

详细可见 Vue 文档 —— KeepAlive (opens new window)

4.1 静态路由的示例

router 路由的 keepAlive 声明如下:

{
  path: '/system/notify-message',
  component: () => import('#/views/system/notify/my/index.vue'),
  name: 'MyNotifyMessage',
  meta: {
    title: '我的站内信',
    icon: 'ant-design:message-filled',
    keepAlive: true, // 开启页面缓存
  },
}

4.2 动态路由的示例

示例