使用 webpack
借助webpack require.context 的能力,可以非常方便地实现上面目录到路由配置的映射工作
require.context函数接受三个参数
- directory {String} -读取文件的路径
- useSubdirectories {Boolean} -是否遍历文件的子目录
- regExp {RegExp} -匹配文件的正则
值得注意的是require.context函数执行后返回的是一个函数,并且这个函数有3个属性
- resolve {Function} -接受一个参数request,request为test文件夹下面匹配文件的相对路径,返回这个匹配文件相对于整个工程的相对路径
- keys {Function} -返回匹配成功模块的名字组成的数组
- id {String} -执行环境的id,返回的是一个字符串,主要用在module.hot.accept,应该是热加载?
这三个都是作为函数的属性(注意是作为函数的属性,函数也是对象,有对应的属性)
const registerRoutes = () => {const contextInfo = require.context('./views', true, /.vue$/)const routes = contextInfo.keys().map((filePath) => {// filePath 形如 ./Home.vue、./modifiers/capture.vue// path我们希望是/home、/modifiers/capture// 所以需要把开头的./和.vue都替换为空const path = filePath.toLowerCase().replace(/^\.|\.vue/g, '')// name的话将/home、/modifiers/capture转成小驼峰即可// 把开头的/先替换掉,再把第一个/后的单词变成大写就可以了const name = path.replace(/^\//, '').replace(/\/(\w)/, ($0, $1) => $1.toUpperCase())// 通过require去读取.vue文件内容const component = require(`./views${filePath.replace(/^\./, '')}`).defaultreturn {path,name,component}})return routes}
// router/index.tsconst files = require.context('./default', false, /\.ts$/)// console.log('🚀 ~ file: index.ts ~ files', files.keys())const defaultRoutes: Array<RouteRecordRaw> = []files.keys().forEach((key) => (defaultRoutes[files(key).menuOrderNo] = files(key).default))console.log('🚀 ~ file: index.ts ~ line 15 ~ defaultRoutes', defaultRoutes)const router = createRouter({history: createWebHistory(process.env.BASE_URL),routes: [...basicRoute,...defaultRoutes,window.localStorage.getItem(TOKEN) ? login404 : logout404]})
使用 vite
import type { App } from 'vue'import type { RouteRecordRaw } from 'vue-router'import { createRouter, createWebHistory } from 'vue-router'import { TOKEN } from 'utils/constant'import { login404, logout404 } from './error'import basicRoute from './basic'import personalCenter from './personalCenter'import controlScreen from './controlScreen'const files = import.meta.glob('./default/*.ts', { eager: true })const defaultRoutes: RouteRecordRaw[] = []for (const path in files) {const file = files[path] as { menuOrderNo: number; default: RouteRecordRaw }defaultRoutes[file.menuOrderNo] = file.default}export const router = createRouter({history: createWebHistory(),routes: [...basicRoute,...defaultRoutes,personalCenter,...controlScreen,window.localStorage.getItem(TOKEN) ? login404 : logout404]})export default function setupRoute(app: App<Element>) {app.use(router)}
