使用 webpack

借助webpack require.context 的能力,可以非常方便地实现上面目录到路由配置的映射工作

require.context函数接受三个参数

  1. directory {String} -读取文件的路径
  2. useSubdirectories {Boolean} -是否遍历文件的子目录
  3. regExp {RegExp} -匹配文件的正则

值得注意的是require.context函数执行后返回的是一个函数,并且这个函数有3个属性

  1. resolve {Function} -接受一个参数request,request为test文件夹下面匹配文件的相对路径,返回这个匹配文件相对于整个工程的相对路径
  2. keys {Function} -返回匹配成功模块的名字组成的数组
  3. id {String} -执行环境的id,返回的是一个字符串,主要用在module.hot.accept,应该是热加载?

这三个都是作为函数的属性(注意是作为函数的属性,函数也是对象,有对应的属性)

  1. const registerRoutes = () => {
  2. const contextInfo = require.context('./views', true, /.vue$/)
  3. const routes = contextInfo.keys().map((filePath) => {
  4. // filePath 形如 ./Home.vue、./modifiers/capture.vue
  5. // path我们希望是/home、/modifiers/capture
  6. // 所以需要把开头的./和.vue都替换为空
  7. const path = filePath.toLowerCase().replace(/^\.|\.vue/g, '')
  8. // name的话将/home、/modifiers/capture转成小驼峰即可
  9. // 把开头的/先替换掉,再把第一个/后的单词变成大写就可以了
  10. const name = path.replace(/^\//, '').replace(/\/(\w)/, ($0, $1) => $1.toUpperCase())
  11. // 通过require去读取.vue文件内容
  12. const component = require(`./views${filePath.replace(/^\./, '')}`).default
  13. return {
  14. path,
  15. name,
  16. component
  17. }
  18. })
  19. return routes
  20. }
  1. // router/index.ts
  2. const files = require.context('./default', false, /\.ts$/)
  3. // console.log('🚀 ~ file: index.ts ~ files', files.keys())
  4. const defaultRoutes: Array<RouteRecordRaw> = []
  5. files
  6. .keys()
  7. .forEach(
  8. (key) => (defaultRoutes[files(key).menuOrderNo] = files(key).default)
  9. )
  10. console.log('🚀 ~ file: index.ts ~ line 15 ~ defaultRoutes', defaultRoutes)
  11. const router = createRouter({
  12. history: createWebHistory(process.env.BASE_URL),
  13. routes: [
  14. ...basicRoute,
  15. ...defaultRoutes,
  16. window.localStorage.getItem(TOKEN) ? login404 : logout404
  17. ]
  18. })

使用 vite

  1. import type { App } from 'vue'
  2. import type { RouteRecordRaw } from 'vue-router'
  3. import { createRouter, createWebHistory } from 'vue-router'
  4. import { TOKEN } from 'utils/constant'
  5. import { login404, logout404 } from './error'
  6. import basicRoute from './basic'
  7. import personalCenter from './personalCenter'
  8. import controlScreen from './controlScreen'
  9. const files = import.meta.glob('./default/*.ts', { eager: true })
  10. const defaultRoutes: RouteRecordRaw[] = []
  11. for (const path in files) {
  12. const file = files[path] as { menuOrderNo: number; default: RouteRecordRaw }
  13. defaultRoutes[file.menuOrderNo] = file.default
  14. }
  15. export const router = createRouter({
  16. history: createWebHistory(),
  17. routes: [
  18. ...basicRoute,
  19. ...defaultRoutes,
  20. personalCenter,
  21. ...controlScreen,
  22. window.localStorage.getItem(TOKEN) ? login404 : logout404
  23. ]
  24. })
  25. export default function setupRoute(app: App<Element>) {
  26. app.use(router)
  27. }