Robot Admin 路由与导航系统详解
等级:进阶 | 阅读时间:9分钟
Robot Admin项目实现了一个全面的路由和导航系统,包括动态路由生成、权限控制和导航守卫。本文将帮助您理解路由系统的工作原理以及如何实现自定义路由。
路由架构概述
Robot Admin中的路由系统基于Vue Router构建,结构设计用于处理公共路由和基于用户权限动态生成的路由。系统由四个主要组件组成:
- index.ts - 核心路由实例配置
- publicRouter.ts - 公共路由定义
- dynamicRouter.ts - 动态路由生成逻辑
- permission.ts - 权限控制与导航守卫
路由配置
核心路由实例在index.ts
中创建,支持哈希和历史模式,可通过环境变量配置。
javascript
// 路由模式通过环境变量配置
const mode = import.meta.env.VITE_ROUTER_MODE as 'hash' | 'history'
const routerMode = {
hash: () => createWebHashHistory(),
history: () => createWebHistory(),
}
const historyCreator = routerMode[mode] || createWebHashHistory
const router = createRouter({
routes,
history: historyCreator(),
strict: false,
scrollBehavior: () => ({ left: 0, top: 0 }),
})
路由类型
公共路由
公共路由始终可访问,无需认证。这些路由定义在publicRouter.ts
中,包括:
- 登录页面
- 错误页面(401, 404)
- 用于处理未知URL的捕获所有路由
javascript
export const publicRoutes: RouteRecordRaw[] = [
{
path: '/login',
name: 'login',
component: () => import('_views/login/index.vue'),
meta: {
title: '登录',
icon: '',
hidden: true,
// 其他元数据...
},
},
// 401, 404和其他公共路由...
]
动态路由
动态路由基于用户权限生成,在成功认证后初始化。系统使用服务器响应来构建路由结构。
路由元属性
每个路由可以包含控制其行为和在导航系统中显示方式的元数据:
属性 | 类型 | 描述 |
---|---|---|
title | string | 在导航和页面标题中显示的路由标题 |
icon | string | 在导航菜单中显示的图标 |
hidden | boolean | 路由是否在导航菜单中隐藏 |
affix | boolean | 路由标签是否固定,不能关闭 |
keepAlive | boolean | 路由组件是否应缓存 |
full | boolean | 路由是否应全屏显示 |
link | string | 如果路由指向外部资源,则为外部链接URL |
动态路由生成
系统提供工具将后端的路由定义转换为实际的Vue Router路由。
路由处理
processRoute
函数将原始路由定义转换为有效的Vue Router路由:
ini
const processRoute = (route: DynamicRoute, isChild = false): RouteRecordRaw => {
return {
...route,
path: normalizePath(route.path, isChild),
component: resolveComponent(route.component),
children: route.children?.map(child => processRoute(child, true)),
meta: {
...route.meta,
isLayout: route.component === 'layout',
},
} as RouteRecordRaw
}
组件解析
组件使用Vite的import.meta.glob功能动态解析:
typescript
const resolveComponent = (path?: string) => {
if (!path) return undefined
// 检查预定义组件
if (path in COMPONENTS) {
return COMPONENTS[path as keyof typeof COMPONENTS]
}
try {
const normalizedPath = path.startsWith('/') ? path : `/${path}`
const viewPath = `/src/views${normalizedPath}.vue`
const modules = import.meta.glob('@/views/**/*.vue')
if (modules[viewPath]) {
return modules[viewPath]
}
// 如果找不到组件,回退到404
return COMPONENTS['404']
} catch (error) {
return COMPONENTS['404']
}
}
初始化动态路由
initDynamicRouter
函数从权限存储中获取路由数据并添加到路由器:
typescript
export const initDynamicRouter = async (): Promise<boolean> => {
try {
const permissionStore = s_permissionStore()
const { code, data: routes, msg } = await permissionStore.getAuthMenuList()
if (code !== '0' || !Array.isArray(routes)) {
throw new Error(msg || '无效的路由数据格式')
}
clearExistingRoutes(['login', '404', '401'])
routes
.map(route => processRoute(route))
.forEach(route => router.addRoute(route))
return true
} catch (error) {
handleRouteError(error)
return false
}
}
权限控制与导航守卫
导航守卫基于认证状态和用户权限控制对路由的访问。
主导航守卫
permission.ts
中的主导航守卫处理多种情况:
- 未认证用户重定向到登录页面(白名单路由除外)
- 已认证用户访问登录页面重定向到主页
- 如果尚未加载,初始化动态路由
- 根据路由元数据设置页面标题
vbnet
router.beforeEach(
async (to: RouteLocationNormalized): Promise<string | boolean> => {
nprogress.start()
try {
const userStore = s_userStore()
const { token } = userStore
const { authMenuList } = s_permissionStore()
const meta = to.meta as ExtendedRouteMeta
// 1. 处理未认证用户
if (!token) {
if (WHITE_LIST.includes(to.path)) {
return true
}
return LOGIN_PATH
}
// 2. 重定向已认证用户从登录页面
if (to.path === LOGIN_PATH) {
return '/'
}
// 3. 如果需要,初始化动态路由
if (!authMenuList.length) {
return await handleDynamicRouterInit(to.fullPath)
}
// 4. 设置页面标题并继续
setPageTitle(meta.title)
return true
} catch (error) {
return handleRouteError(error)
}
}
)
路由加载进度
系统使用NProgress在路由导航期间显示加载指示器:
scss
const nprogress = setupNProgress()
// 导航前开始进度指示器
router.beforeEach(() => {
nprogress.start()
})
// 导航后完成进度指示器
router.beforeEach(() => {
// ...其他逻辑
nprogress.done()
})
添加自定义路由
创建静态公共路由
要添加无需认证的新公共路由:
将您的路由添加到publicRouter.ts
中的publicRoutes
数组:
javascript
export const publicRoutes: RouteRecordRaw[] = [
// 现有路由...
{
path: '/public-dashboard',
name: 'publicDashboard',
component: () => import('@/views/public/Dashboard.vue'),
meta: {
title: 'Public Dashboard',
icon: 'dashboard',
hidden: false,
keepAlive: true,
},
},
]
为后端集成创建动态路由
对于应包含在动态路由系统中的路由:
确保您的后端API以正确的格式返回路由定义:
css
// 后端响应示例格式
{
code: '0',
data: [
{
path: '/dashboard',
name: 'Dashboard',
component: 'layout',
redirect: '/dashboard/analysis',
meta: { title: 'Dashboard', icon: 'dashboard' },
children: [
{
path: 'analysis',
name: 'Analysis',
component: 'dashboard/Analysis',
meta: { title: 'Analysis', keepAlive: true }
}
]
}
],
msg: 'success'
}
在src/views
目录中创建与路由定义中的组件字符串匹配的视图组件。
常见路由模式
嵌套路由
使用父布局组件创建嵌套路由:
css
{
path: '/parent',
component: 'layout',
redirect: '/parent/child',
meta: { title: 'Parent Menu' },
children: [
{
path: 'child',
component: 'parent/Child',
meta: { title: 'Child Page' }
}
]
}
带参数的路由
创建带动态参数的路由:
css
{
path: '/user/:id',
component: 'user/Detail',
meta: { title: 'User Detail' }
}
外部链接
创建链接到外部站点的菜单项:
rust
{
path: 'https://github.com/ChenyCHENYU/Robot_Admin',
meta: {
title: 'GitHub Repository',
link: true // 此标志表示外部链接
}
}
调试路由
在开发模式下,系统提供路由导航的调试日志:
javascript
// 开发中的调试日志
if (import.meta.env.DEV)
router.afterEach(to => console.debug('[动态路由] 导航至:', to.path))
您也可以在浏览器控制台中检查当前路由:
arduino
// 在浏览器控制台
console.log(router.getRoutes())
最佳实践
- 组件懒加载:始终使用动态导入路由组件,以启用代码拆分并提高性能。
- 路由元属性:一致使用元属性控制路由在导航菜单和布局中的行为。
- 错误处理:为路由解析和导航实现适当的错误处理,以提供更好的用户体验。
- 测试:彻底测试您的路由,尤其是在实现动态路由生成时,确保所有路径正确解析。
- 路由名称:使用一致且描述性的路由名称,以便于调试和程序化导航。
总结
通过遵循这些指南并理解Robot Admin中的路由架构,您可以有效地实现和自定义应用程序所需的路由。Robot Admin的路由系统提供了完整的权限控制、动态路由生成和灵活的导航管理,为构建企业级应用奠定了坚实的基础。
相关链接:
期待共建!
如果这套组件系统对你的开发工作有所启发或帮助,请不要吝啬你的 Star!每一个 ⭐ 都是对我最大的鼓励和支持。
👉 点击这里 Star 支持项目 (🧧行大运摸大票💰)
🔗 探索更多资源
📋 资源类型 | 🔗 链接 | 📝 说明 |
---|---|---|
🎯 在线预览 | robotadmin.cn | 体验完整功能演示 |
📚 详细文档 | tzagileteam.com | 深入了解实现细节 |
💻 源码仓库 | https:/github.com/ChenyCHENYU/Robot_Admin | 获取完整源代码 |