动态生成路由
vue3+vite3根据目录动态生成路由
页面层级
text
├── App.vue
├── main.ts
├── router
│ ├── index.ts
│ └── pTest.ts
├── store
│ └──test.store.ts
├── utils
│ ├── index.ts
│ ├── ...
│ └── interceptor.ts
└── views
├── pTest
│ ├── components
│ ├── test
│ │ └── testA.vue
│ ├── testA.vue
│ └── testB.vue
└── pageQuickIn.vue
routerGenerate
- 约定如下:
- 例:页面如下 views/pTest/testA
- 1: path => pTest/testA
- 2: name => PTestTestA
- 3: meta => pagesOptions中配置
ts
import { RouteRecordRaw } from 'vue-router'
/**
* 动态生成路由
* @param viteModules https://cn.vitejs.dev/guide/features#glob-import
*/
export function routerGenerate(
viteModules: Record<string, () => Promise<any>>,
pagesOptions: any = {}
): Array<RouteRecordRaw> {
// 过滤掉components下的vue文件
const _viteModules = Object.keys(viteModules)
.filter(key => !key.includes('components'))
.reduce(
(acc, key) => {
acc[key] = viteModules[key]
return acc
},
{} as typeof viteModules
)
const routes: Array<RouteRecordRaw> = Object.entries(_viteModules).map(([modulePath, component]) => {
// path 页面路由 目录路径 如:/pTest/testA
const path = modulePath.replace('../views', '').replace('.vue', '') || '/'
// 目录层级拆分 ['',pTest,testA],['',pTest,test,testA],
const pathArr = path.split('/')
const pathArrLen = pathArr.length
// 模块文件目录层级-数组形式 [pTest,testA],[pTest,test,testA]
const nameArr = pathArr.slice(1, pathArrLen)
// console.log(nameArr);
const name = nameArr
.map(_e => {
return _e.replace(/^[a-z]/, match => match.toUpperCase())
})
.join('') // 页面name 路径拼接-驼峰 PTestTestA PTestTestTestA
// 当前页面配置 routeNameArr.join('/')页面所在分包path 用于匹配页面配置
const currentPageOptions = pagesOptions[pathArr.slice(2, pathArrLen).join('/')]
// console.log(currentPageOptions);
return {
path: path + (currentPageOptions?.routeParam || ''),
meta: currentPageOptions?.meta || {},
name,
component
}
})
// console.log(routes);
return routes
}
pTest.router
ts
import { RouteRecordRaw } from 'vue-router'
import { routerGenerate } from '@/common/utils'
// pagesOptions
const pTestPagesOptions = {
// testA: {
// meta: {
// title: '测试页面A',
// KeepAlive: true,
// },
// },
// 'test/testA': {
// meta: {
// title: '测试页面A',
// KeepAlive: true,
// },
// routeParam: '/:id',
// },
}
const routes: Array<RouteRecordRaw> = routerGenerate(import.meta.glob('../views/pTest/**/*.vue'), pTestPagesOptions)
export default routes
createRouter
ts
import { createRouter, RouteRecordRaw, createWebHashHistory } from 'vue-router'
import pTest from './pTest'
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'pageQuickIn',
meta: {
title: '',
keepAlive: false
},
component: () => import('../views/pageQuickIn.vue'),
// redirect: '/pTest/testA',
children: []
},
...pTest
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router