动态路由是整个后台管理系统中最核心的部分,这里是来介绍一下动态路由是怎样实现的吧。
动态路由的实现
- 将各个模块的路由保存在一个单独的文件,如下:
typescript
export default {
path: '/',
name: 'Layout',
component: () => import('@/layout/index.vue'),
redirect: '/home',
children: [
{
path: 'home',
name: 'Home',
component: () => import('@/views/home/index.vue'),
meta: {
title: '项目介绍',
isShow: true,
},
},
{
path: 'user',
name: 'User',
component: () => import('@/views/user/index.vue'),
meta: {
title: '用户列表',
isShow: true,
},
},
{
path: 'role',
name: 'Role',
component: () => import('@/views/role/index.vue'),
meta: {
title: '角色列表',
isShow: true,
},
},
{
path: 'auth',
name: 'Auth',
component: () => import('@/views/auth/index.vue'),
meta: {
title: '权限列表',
isShow: true,
},
},
],
}
typescript
export default {
path: '/login',
name: 'login',
component: () => import('@/views/login/index.vue'),
children: [],
}
- 使用vite提供的api动态加载所有的这些单独的路由文件
typescript
const modules: Record<string, any> = import.meta.glob('./modules/*.ts', {
eager: true,
})
- 循环得到的modules,配置router
typescript
const routes: Array<RouteRecordRaw> = []
Object.keys(modules).forEach((key) => {
const module = modules[key]
routes.push(module.default)
})
最终得到的routes数据就是最终的路由配置对象,然后将这个配置对象传给路由对象。
typescript
const router = createRouter({
history: createWebHashHistory(),
routes,
})
动态路由渲染动态导航菜单
在后台管理系统中,路由是与导航菜单相辅相成的,接下来介绍一下导航菜单的渲染。具体步骤如下:
- 通过Vue提供的useRouter方法动态获取所有路由对象
- 利用Element Plus提供的el-menu组件遍历所有路由对象形成导航菜单
具体实现如下:
typescript
import { useRouter, useRoute } from 'vue'
const route = useRoute()
const router = useRouter()
const routes = router.getRoutes()
const menuList = routes.filter((route) => {
return route.meta.isShow
})
vue
<el-menu
:default-active="activePath"
class="el-menu-vertical-demo"
background-color="#545c64"
router
>
<template v-for="item in menuList" :key="item.name">
<template v-if="!item.children">
<el-menu-item :index="item.path">
{{ item.meta!.title }}
</el-menu-item>
</template>
<template v-else>
<el-sub-menu :index="item.path">
<template #title>
<span>{{ item.meta?.title }}</span>
</template>
<template
v-for="subItem in item.children"
:key="subItem.path"
>
<el-menu-item :index="subItem.path">
{{ subItem.meta?.title }}
</el-menu-item>
</template>
</el-sub-menu>
</template>
</template>
</el-menu>