# 路由
>[warning] 此文档可忽略,JeecgBoot已经改造 直接通过后台配置菜单即可,
> 保留文档目的:便于大家理解前端菜单的原生实现。
项目路由配置存放于[src/router/routes](https://github.com/jeecgboot/jeecgboot-vue3/tree/master/src/router/routes)下面。[src/router/routes/modules](https://github.com/jeecgboot/jeecgboot-vue3/tree/master/src/router/routes/modules)用于存放路由模块,在该目录下的文件会自动注册。
## 配置
### 模块说明
在[src/router/routes/modules](https://github.com/jeecgboot/jeecgboot-vue3/tree/master/src/router/routes/modules)内的`.ts`文件会被视为一个路由模块。
一个路由模块包含以下结构
~~~
import type { AppRouteModule } from '/@/router/types';
import { LAYOUT } from '/@/router/constant';
import { t } from '/@/hooks/web/useI18n';
const dashboard: AppRouteModule = {
path: '/dashboard',
name: 'Dashboard',
component: LAYOUT,
redirect: '/dashboard/analysis',
meta: {
icon: 'ion:grid-outline',
title: t('routes.dashboard.dashboard'),
},
children: [
{
path: 'analysis',
name: 'Analysis',
component: () => import('/@/views/dashboard/analysis/index.vue'),
meta: {
affix: true,
title: t('routes.dashboard.analysis'),
},
},
{
path: 'workbench',
name: 'Workbench',
component: () => import('/@/views/dashboard/workbench/index.vue'),
meta: {
title: t('routes.dashboard.workbench'),
},
},
],
};
export default dashboard;
~~~
### 多级路由
注意事项
* 整个项目所有路由`name`不能重复
* 所有的多级路由最终都会转成二级路由,所以不能内嵌子路由
* 除了 layout 对应的 path 前面需要加`/`,其余子路由都不要以`/`开头
**示例**
~~~
import type { AppRouteModule } from '/@/router/types';
import { getParentLayout, LAYOUT } from '/@/router/constant';
import { t } from '/@/hooks/web/useI18n';
const permission: AppRouteModule = {
path: '/level',
name: 'Level',
component: LAYOUT,
redirect: '/level/menu1/menu1-1/menu1-1-1',
meta: {
icon: 'ion:menu-outline',
title: t('routes.demo.level.level'),
},
children: [
{
path: 'tabs/:id',
name: 'TabsParams',
component: getParentLayout('TabsParams'),
meta: {
carryParam: true,
hidePathForChildren: true, // 本级path将会在子级菜单中合成完整path时会忽略这一层级
},
children: [
path: 'tabs/id1', // 其上级有标记hidePathForChildren,所以本级在生成菜单时最终的path为 /level/tabs/id1
name: 'TabsParams',
component: getParentLayout('TabsParams'),
meta: {
carryParam: true,
ignoreRoute: true, // 本路由仅用于菜单生成,不会在实际的路由表中出现
},
]
},
{
path: 'menu1',
name: 'Menu1Demo',
component: getParentLayout('Menu1Demo'),
meta: {
title: 'Menu1',
},
redirect: '/level/menu1/menu1-1/menu1-1-1',
children: [
{
path: 'menu1-1',
name: 'Menu11Demo',
component: getParentLayout('Menu11Demo'),
meta: {
title: 'Menu1-1',
},
redirect: '/level/menu1/menu1-1/menu1-1-1',
children: [
{
path: 'menu1-1-1',
name: 'Menu111Demo',
component: () => import('/@/views/demo/level/Menu111.vue'),
meta: {
title: 'Menu111',
},
},
],
},
],
},
],
};
export default permission;
~~~
### Meta 配置说明
~~~
export interface RouteMeta {
// 路由title 一般必填
title: string;
// 动态路由可打开Tab页数
dynamicLevel?: number;
// 动态路由的实际Path, 即去除路由的动态部分;
realPath?: string;
// 是否忽略权限,只在权限模式为Role的时候有效
ignoreAuth?: boolean;
// 可以访问的角色,只在权限模式为Role的时候有效
roles?: RoleEnum[];
// 是否忽略KeepAlive缓存
ignoreKeepAlive?: boolean;
// 是否固定标签
affix?: boolean;
// 图标,也是菜单图标
icon?: string;
// 内嵌iframe的地址
frameSrc?: string;
// 指定该路由切换的动画名
transitionName?: string;
// 隐藏该路由在面包屑上面的显示
hideBreadcrumb?: boolean;
// 如果该路由会携带参数,且需要在tab页上面显示。则需要设置为true
carryParam?: boolean;
// 隐藏所有子菜单
hideChildrenInMenu?: boolean;
// 当前激活的菜单。用于配置详情页时左侧激活的菜单路径
currentActiveMenu?: string;
// 当前路由不再标签页显示
hideTab?: boolean;
// 当前路由不再菜单显示
hideMenu?: boolean;
// 菜单排序,只对第一级有效
orderNo?: number;
// 忽略路由。用于在ROUTE_MAPPING以及BACK权限模式下,生成对应的菜单而忽略路由。2.5.3以上版本有效
ignoreRoute?: boolean;
// 是否在子级菜单的完整path中忽略本级path。2.5.3以上版本有效
hidePathForChildren?: boolean;
}
~~~
### 外部页面嵌套
只需要将`frameSrc`设置为需要跳转的地址即可
~~~
const IFrame = () => import('/@/views/sys/iframe/FrameBlank.vue');
{
path: 'doc',
name: 'Doc',
component: IFrame,
meta: {
frameSrc: 'http://www.jeecg.com',
title: t('routes.demo.iframe.doc'),
},
},
~~~
### 外链
只需要将`path`设置为需要跳转的**HTTP 地址**即可
~~~
{
path: 'http://www.jeecg.com',
name: 'DocExternal',
component: IFrame,
meta: {
title: t('routes.demo.iframe.docExternal'),
},
}
~~~
### 动态路由Tab自动关闭功能
若需要开启该功能,需要在动态路由的`meta`中设置如下两个参数:
* `dynamicLevel`最大能打开的Tab标签页数
* `realPath`动态路由实际路径(考虑到动态路由有时候可能存在N层的情况, 例:`/:id/:subId/:...`), 为了减少计算开销, 使用配置方式事先规定好路由的实际路径(注意: 该参数若不设置,将无法使用该功能)
~~~
{
path: 'detail/:id',
name: 'TabDetail',
component: () => import('/@/views/demo/feat/tabs/TabDetail.vue'),
meta: {
currentActiveMenu: '/feat/tabs',
title: t('routes.demo.feat.tabDetail'),
hideMenu: true,
dynamicLevel: 3,
realPath: '/feat/tabs/detail',
},
}
~~~
## 图标
这里的`icon`配置,会同步到**菜单**(icon 的值可以查看[此处](icon.md))。
## 新增路由
### 如何新增一个路由模块
1. 在[src/router/routes/modules](https://github.com/jeecgboot/jeecgboot-vue3/tree/master/src/router/routes/modules)内新增一个模块文件。
示例,新增 test.ts 文件
~~~
import type { AppRouteModule } from '/@/router/types';
import { LAYOUT } from '/@/router/constant';
import { t } from '/@/hooks/web/useI18n';
const dashboard: AppRouteModule = {
path: '/about',
name: 'About',
component: LAYOUT,
redirect: '/about/index',
meta: {
icon: 'simple-icons:about-dot-me',
title: t('routes.dashboard.about'),
},
children: [
{
path: 'index',
name: 'AboutPage',
component: () => import('/@/views/sys/about/index.vue'),
meta: {
title: t('routes.dashboard.about'),
icon: 'simple-icons:about-dot-me',
},
},
],
};
export default dashboard;
~~~
此时路由已添加完成,不需要手动引入,放在[src/router/routes/modules](https://github.com/jeecgboot/jeecgboot-vue3/tree/master/src/router/routes/modules)内的文件会自动被加载。
### 验证
访问**ip:端口/about/index**出现对应组件内容即代表成功
## 路由刷新
项目中采用的是**重定向**方式
### 实现
~~~
import { useRedo } from '/@/hooks/web/usePage';
import { defineComponent } from 'vue';
export default defineComponent({
setup() {
const redo = useRedo();
// 执行刷新
redo();
return {};
},
});
~~~
### Redirect
[src/views/sys/redirect/index.vue](https://github.com/jeecgboot/jeecgboot-vue3/tree/master/src/views/sys/redirect/index.vue)
~~~
import { defineComponent, unref } from 'vue';
import { useRouter } from 'vue-router';
export default defineComponent({
name: 'Redirect',
setup() {
const { currentRoute, replace } = useRouter();
const { params, query } = unref(currentRoute);
const { path } = params;
const _path = Array.isArray(path) ? path.join('/') : path;
replace({
path: '/' + _path,
query,
});
return {};
},
});
~~~
## 页面跳转
页面跳转建议采用项目提供的`useGo`
### 方式
~~~
import { useGo } from '/@/hooks/web/usePage';
import { defineComponent } from 'vue';
export default defineComponent({
setup() {
const go = useGo();
// 执行刷新
go();
go(PageEnum.Home);
return {};
},
});
~~~
## 多标签页
标签页使用的是`keep-alive`和`router-view`实现,实现切换 tab 后还能保存切换之前的状态。
### 如何开启页面缓存
开启缓存有 3 个条件
1. 在[src/settings/projectSetting.ts](https://github.com/jeecgboot/jeecgboot-vue3/tree/master/src/settings/projectSetting.ts)内将`openKeepAlive`设置为`true`
2. 路由设置`name`,且**不能重复**
3. 路由对应的组件加上`name`,与路由设置的`name`保持一致
~~~
{
...,
// name
name: 'Login',
// 对应组件组件的name
component: () => import('/@/views/sys/login/index.vue'),
...
},
// /@/views/sys/login/index.vue
export default defineComponent({
// 需要和路由的name一致
name:"Login"
});
~~~
注意
keep-alive 生效的前提是:需要将路由的`name`属性及对应的页面的`name`设置成一样。因为:
**include - 字符串或正则表达式,只有名称匹配的组件会被缓存**
### 如何让某个页面不缓存
**可在 router.meta 下配置**
可以将`ignoreKeepAlive`配置成`true`即可关闭缓存。
~~~
export interface RouteMeta {
// 是否忽略KeepAlive缓存
ignoreKeepAlive?: boolean;
}
~~~
## 如何更改首页路由
首页路由指的是应用程序中的默认路由,当不输入其他任何路由时,会自动重定向到该路由下,并且该路由在Tab上是固定的,即使设置`affix: false`也不允许关闭
例:首页路由配置的是`/dashboard/analysis`,那么当直接访问`http://localhost:3100/`会自动跳转到`http://localhost:3100/#/dashboard/analysis`上(用户已登录的情况下)
可以将`pageEnum.ts`中的`BASE_HOME`更改为需要你想设置的首页即可
~~~
export enum PageEnum {
// basic home path
// 更改此处即可
BASE_HOME = '/dashboard',
}
~~~
- 项目介绍
- 常见问题
- 开发环境准备
- 环境准备
- 启动项目
- 切换Vue3路由
- 项目配置详细说明
- 上线部署
- 快速构建&部署
- Docker镜像启动
- 项目配置
- 菜单配置
- 菜单缓存
- 积木报表菜单配置
- 首页配置
- 国际化
- 菜单国际化
- 组件注册
- 项目规范
- 跨域处理
- 样式库
- 图标生成
- package依赖介绍
- 菜单TAB风格
- 备份文档
- 详细构建和配置
- 构建部署1.0
- 切换Mock接口
- 原生路由(作废)
- 原生菜单(作废)
- 页面开启缓存(作废)
- 环境准备1.0
- 数据 mock&联调
- UI组件
- Form 表单组件
- Table 表格
- Modal 弹窗
- Drawer 抽屉组件
- Icon 图标组件
- Button 按钮
- 更多基础组件
- JSelectUser选择用户 ✔
- JSelectPosition岗位选择 ✔
- JSelectDept部门选择 ✔
- JCheckbox ✔
- JImportModal 列表导入弹窗组件
- JInput特殊查询组件 ✔
- JPopup弹窗选择组件 ✔
- JTreeSelect树形下拉框 (异步加载) ✔
- JAreaSelect 省市县级联组件
- JDictSelectTag 字典标签 ✔
- JEllipsis 超长截取显示组件 ✔
- JUpload 上传组件 ✔
- JEasyCron 定时表达式选择组件 ✔
- JInputPopup 多行输入窗口组件 ✔
- JSwitch 开关选择组件 ✔
- JTreeDict 分类字典树形下拉组件 ✔
- JSelectInput 可输入下拉框 ✔
- JEditor 富文本编辑器 ✔
- JMarkdownEditor Markdown编辑器 ✔
- JSearchSelect 字典表的搜索组件 ✔
- JSelectUserByDept 根据部门选择用户 ✔
- JVxeTable
- 组件配置文档
- 自定义组件
- 封装自定义组件
- 自定义组件增强
- 多级联动配置
- 使用示例
- 常见问题解答
- JAreaLinkage 省市县联动组件 ✔
- JCategorySelect 分类字典树 ✔
- JImageUpload 图片上传 ✔
- JSelectMultiple 下拉多选 ✔
- JSelectRole 选择角色 ✔
- JFormContainer 表单组件禁用 ✔
- SuperQuery 高级查询
- UserSelect 高级用户选择组件
- Basic
- Page
- Authority
- PopConfirmButton
- CollapseContainer
- ScrollContainer
- LazyContainer
- CodeEditor
- JsonPreview
- CountDown
- ClickOutSide
- CountTo
- Cropper
- Description
- FlowChart
- Upload
- Tree
- Excel
- Qrcode
- Markdown
- Loading
- Tinymce
- Time
- StrengthMeter
- Verify
- Transition
- VirtualScroll
- ContextMenu
- Preview
- Loading
- 前端权限
- 表单权限
- 显隐控制 ✔
- 禁用控制 ✔
- 列表权限
- 按钮权限控制
- 列字段显隐控制
- 行编辑组件权限
- 显隐控制
- 禁用控制
- 代码生成
- Online在线代码生成
- GUI代码生成
- 代码生成模板介绍
- vue3和vue3Native详细说明
- 深入开发
- 定义Form新组件
- 自定义列表查询
- 自定义表单布局
- 开发笔记
- 组件权限控制
- 使用Antd Vue原生Form
- 自定义图表组件
- 自定义渲染函数
- 如何编写mock接口
- 缓存用法
- 精简版代码制作
- 微前端(qiankun)集成
- 前端小技巧
- 表单整体禁用
- 弹框内下拉框错位
- 界面如何设置响应式
- 抽屉(Drawer)宽度自适应
- 生成菜单脚本
- Online表单
- Online常见问题
- Online表单配置
- 配置参数说明
- 系统标准字段
- 表单类型-主子表|树表
- 自定义查询配置
- Online表单风格
- Online表单删除说明
- Online联合查询配置
- online表单视图功能说明
- Online表单开启评论
- Online表单控件介绍
- 常用基础控件
- 高级关联记录
- Online表单控件配置
- 基本配置
- 控件扩展配置
- 默认值表达式
- 自定义查询配置
- 字段href
- 默认值(填值规则)
- 导入导出自定义规则
- Online表单权限配置
- 字段权限配置与授权
- 按钮权限配置与授权
- 数据权限配置与授权
- 联合查询数据权限规则说明
- 在线增强
- 自定义按钮
- SQL增强
- JS增强
- 按钮触发JS增强
- 列表Api
- 列表操作列前置事件
- 表单Api
- beforeSubmit事件
- loaded事件
- 表单值改变事件【单表/主表】
- 表单值改变事件【从表】
- 表单值改变事件【从改主】
- 控制字段显示与隐藏
- js增强实现下拉联动
- js增强控制下拉树数据
- JS增强 触发弹窗
- JS增强 http请求
- JS增强 方法定义
- 对接表单设计器后需注意
- JAVA增强
- 快速开始
- Online java增强 导入
- Online java增强 导出
- Online java增强 查询
- Online Java增强 http-api
- 表单类
- 列表类
- 其他功能示例
- 导入数据库表支持排除表
- 通过字段Href实现三级联动
- excel数据导入支持校验
- Online报表
- Online报表配置
- 配置成菜单
- 其他功能
- 推送消息
- ISO 8601书写格式
- 系统消息跳转至详情表单
- 菜单【批量申请(自定义)】功能说明
- Online自动化测试
- online AI自动化测试数据制作
- Online AI自动化测试数据制作
- Online AI模型测试用例功能详情
- JAVA后台功能
- saas多租户切换
- 新功能实现saas租户隔离
- 第三方集成
- 敲敲云集成钉钉