概述
工程化项目中,有时候可能一个项目会有多个路由页面,每次新加路由页面都需要去修改路由配置文件,如果我们可以在约定的目录情况下,自动根据目录结构生成对应的路由结构,就不用每次路由新增的时候都去改配置文件,实现自动化(前提团队约约定俗成目录结构)。
关键点
工程化项目,我们最终页面看到的都是打包后的代码加载出来的,而我们代码目录结构是存在编译时的,如果要在打包过程中读取到源码目录结构,需要使用如下api,根据环境的不同,对应实现也不一样。
vite环境
import.meta.glob
webpack环境
require.context
实现
目录结构
- xxx/page.js路由配置其他信息
- xxx/xxx.vue,为路由组件
js
src/
views/
about/
index.vue
page.js
home/
index.vue
page.js
/router
index.js
router/index.js
js
import { createWebHistory, createRouter } from 'vue-router'
const data = import.meta.glob("../views/**/page.js", {
eager: true,
import: "default"
})
const components = import.meta.glob("../views/**/index.vue", {
eager: true,
import: "default"
})
const routes = Object.entries(data).map(([path, meta]) => {
console.log("path, meta--", path, meta)
const newPath = path.replace("../views", "").replace("/page.js", "").toLowerCase() || "/"
const name = newPath.split("/").join("-").replace(/^-/, "") || "index"
const componentPath = path.replace("/page.js", "/index.vue")
const callbackfn = components[componentPath]
return {
path: newPath,
meta: meta,
name,
component: callbackfn
}
})
const router = createRouter({
history: createWebHistory("/"),
routes,
})
export default router
views/about/index.vue
js
<template>
<div>about</div>
</template>
<script setup></script>
views/home/index.vue
js
<template>
<div>home</div>
</template>
<script setup></script>
注意
import.meta.glob是在编译时运行的,在打包后,vite工具会将我们源代码转成如下示例:
源代码
js
// src/main.js
const components = import.meta.glob('./components/[A-Z]*.vue', {
eager: true,
import: 'default'
})
编译后
js
// 编译后的代码(简化)
const components = {
'./components/Button.vue': ButtonComponent,
'./components/Input.vue': InputComponent,
'./components/Modal.vue': ModalComponent
// 注意:不匹配 [A-Z]*.vue 模式的文件不会被包含
}
webpack环境下的require.context同理
总结
按照约定的路由模块的文件模块层级写法,我们就不需要重复去配置来路由了,只需要按照目录规范书写代码和配置即可,当然,除上面的方法外,我们还可以直接使用node读取模块,然后自动生成路由文件。
扩展应用
除上面的自动注册路由之外,我们还可以扩展如下自动化相关功能
- 自动注册组件
- 功能模块聚合
- 状态管理模块注册
- 多语言模块自动生成
- ....