JeecgBoot前端路由:Vue Router动态路由配置
你是否还在为企业级应用中的路由权限管理感到头疼?是否遇到过不同角色需要展示不同菜单的需求?本文将带你一文掌握JeecgBoot中基于Vue Router的动态路由解决方案,从基础配置到高级应用,让你轻松应对复杂权限场景。
路由系统架构概览
JeecgBoot前端路由系统采用模块化设计,主要由路由实例创建、路由配置和权限控制三部分组成。核心文件结构如下:
- 路由实例:src/router/index.ts
- 路由配置:src/router/routes/index.ts
- 路由类型定义:src/router/types.ts
- 路由守卫:src/router/guard/index.ts
路由初始化流程
基础路由配置
基础路由是不需要权限控制的公共路由,如登录页、404页等。在JeecgBoot中,这些路由定义在basicRoutes数组中。
核心代码示例
// src/router/routes/index.ts
export const basicRoutes = [
LoginRoute, // 登录路由
RootRoute, // 根路由
...mainOutRoutes, // 外部链接路由
REDIRECT_ROUTE, // 重定向路由
PAGE_NOT_FOUND_ROUTE,// 404路由
TokenLoginRoute, // Token登录路由
Oauth2LoginRoute // OAuth2登录路由
];
路由类型定义
JeecgBoot扩展了Vue Router的路由类型,定义了AppRouteRecordRaw接口,增加了权限相关的元数据:
// src/router/types.ts
export interface AppRouteRecordRaw extends RouteRecordRaw {
name: string;
meta: AppRouteMeta;
children?: AppRouteRecordRaw[];
props?: Recordable;
fullPath?: string;
}
export interface AppRouteMeta {
// 菜单名称
title: string;
// 是否忽略权限
ignoreAuth?: boolean;
// 角色权限
roles?: RoleEnum[];
// 是否缓存
keepAlive?: boolean;
// 图标
icon?: string;
// 路由顺序
orderNo?: number;
}
动态路由实现
动态路由是根据用户角色动态生成的路由,JeecgBoot通过以下步骤实现:
1. 模块化路由加载
系统会自动扫描src/router/routes/modules目录下的所有路由模块文件:
// src/router/routes/index.ts
const modules = import.meta.glob('./modules/**/*.ts', { eager: true });
const routeModuleList: AppRouteModule[] = [];
// 加入到路由集合中
Object.keys(modules).forEach((key) => {
const mod = (modules as Recordable)[key].default || {};
const modList = Array.isArray(mod) ? [...mod] : [mod];
routeModuleList.push(...modList);
});
export const asyncRoutes = [PAGE_NOT_FOUND_ROUTE, ...routeModuleList];
2. 路由权限过滤
在获取后端返回的路由数据后,需要根据用户权限进行过滤:
// src/router/helper/routeHelper.ts
export function filterRouteByPermission(routes: AppRouteRecordRaw[], permissions: string[]): AppRouteRecordRaw[] {
const res: AppRouteRecordRaw[] = [];
routes.forEach(route => {
const temp = { ...route };
// 检查路由是否有权限要求
if (!temp.meta?.roles || temp.meta.roles.some(role => permissions.includes(role))) {
if (temp.children) {
temp.children = filterRouteByPermission(temp.children, permissions);
}
res.push(temp);
}
});
return res;
}
3. 动态路由添加
通过router.addRoute方法将过滤后的路由添加到路由实例中:
// src/router/index.ts
export function addDynamicRoutes(routes: AppRouteRecordRaw[]) {
routes.forEach(route => {
// 处理路由组件
if (route.component === 'LAYOUT') {
route.component = LAYOUT;
}
router.addRoute(route);
// 递归添加子路由
if (route.children && route.children.length) {
addDynamicRoutes(route.children);
}
});
}
路由权限控制
JeecgBoot的路由权限控制基于RBAC(Role-Based Access Control)模型,通过路由元信息中的roles字段实现。
权限控制流程图
路由元信息配置示例
// src/router/routes/modules/system.ts
export default {
path: '/system',
name: 'System',
component: LAYOUT,
meta: {
title: '系统管理',
icon: 'ion:settings-outline',
roles: ['admin', 'system_manager'], // 只有admin和system_manager角色可见
orderNo: 10
},
children: [
{
path: 'user',
name: 'User',
component: () => import('/@/views/system/user/index.vue'),
meta: {
title: '用户管理',
roles: ['admin'], // 只有admin角色可见
}
},
// 更多子路由...
]
} as AppRouteModule;
路由高级应用
路由缓存策略
JeecgBoot通过路由元信息的keepAlive字段控制页面缓存:
{
path: 'dashboard',
name: 'Dashboard',
component: () => import('/@/views/dashboard/index.vue'),
meta: {
title: '仪表盘',
keepAlive: true, // 开启缓存
ignoreAuth: true
}
}
缓存实现的核心代码在src/layouts/default/index.vue中:
<template>
<RouterView v-slot="{ Component, route }">
<transition name="fade-transform" mode="out-in">
<keep-alive :include="keepAliveComponents">
<component :is="Component" :key="route.fullPath" />
</keep-alive>
</transition>
</RouterView>
</template>
路由参数传递
在JeecgBoot中传递路由参数有两种常用方式:
- 查询参数:
/user?id=123 - 路径参数:
/user/123
路径参数需要在路由定义中声明:
{
path: 'user/:id',
name: 'UserDetail',
component: () => import('/@/views/system/user/Detail.vue'),
meta: {
title: '用户详情',
roles: ['admin']
},
props: true // 将路径参数映射为组件props
}
在组件中使用:
export default defineComponent({
props: {
id: {
type: String,
required: true
}
},
setup(props) {
// 使用props.id获取参数
console.log('用户ID:', props.id);
}
});
路由切换动画
JeecgBoot内置了多种路由切换动画,定义在src/design/transition/index.less中。可以通过路由元信息的transition字段指定:
{
path: 'form',
name: 'Form',
component: () => import('/@/views/demo/form/index.vue'),
meta: {
title: '表单示例',
transition: 'slide-right' // 指定动画效果
}
}
常见问题解决方案
路由刷新404问题
当使用history模式时,刷新页面可能会出现404错误。解决方案是在后端配置所有路由都重定向到index.html,同时在前端配置PAGE_NOT_FOUND_ROUTE:
// src/router/routes/basic.ts
export const PAGE_NOT_FOUND_ROUTE: AppRouteRecordRaw = {
path: '/:path(.*)*',
name: 'PageNotFound',
component: () => import('/@/views/sys/exception/404.vue'),
meta: {
title: '404',
ignoreAuth: true
}
};
动态路由刷新丢失问题
解决动态路由刷新丢失的关键是在应用初始化时重新加载路由:
// src/main.ts
async function bootstrap() {
const app = createApp(App);
// 初始化路由
await setupRouter(app);
app.mount('#app');
}
bootstrap();
// src/router/index.ts
export async function setupRouter(app: App) {
// 先重置路由
resetRouter();
const router = createRouter();
app.use(router);
// 加载动态路由
await router.push(PageEnum.BASE_HOME);
return router;
}
总结与展望
JeecgBoot的路由系统基于Vue Router构建,通过动态路由和权限控制实现了复杂的企业级应用需求。主要特点包括:
- 模块化路由配置:将路由按功能模块拆分,便于维护
- 细粒度权限控制:支持基于角色的路由访问控制
- 灵活的缓存策略:可配置的页面缓存机制
- 丰富的路由元信息:支持标题、图标、排序等多种元数据
未来JeecgBoot路由系统可能会引入更多高级特性,如路由懒加载优化、路由状态管理等,进一步提升大型应用的性能和开发效率。
掌握JeecgBoot的动态路由配置,不仅能解决当前项目中的权限管理问题,还能为你深入理解前端架构设计提供实践经验。赶快在你的项目中尝试这些技巧吧!
如果你觉得本文对你有帮助,别忘了点赞、收藏、关注三连,下期我们将介绍JeecgBoot的表单设计器高级用法!
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



