Vue工程化实现约定式路由自动注册
获取编译时态的目录结构方式:
-
webpack工程: require.context()
-
vite工程: import.meta.glob()
约定式路由自动注册(vite)
// router/index.js 路由模块import { createRouter, createWebHistory } from "vue-router";const modules = import.meta.glob("../views/**/index.vue");const autoRoutes = Object.keys(modules).map((path) => {const name = path.match(/\.\.\/views\/(.*?)\/index\.vue$/)[1];return {path: `/${name}`,component: modules[path],name: name.replace(/\//g, "-"), // 处理多级目录};
});// 手动配置部分
const manualRoutes = [{path: "/",name: "home",component: () => import("../views/HomeView.vue"),meta: { requiresAuth: false },},// {// path: "/:pathMatch(.*)*",// component: () => import("@/views/404/index.vue"),// },
];export default createRouter({history: createWebHistory(),routes: [...manualRoutes, ...autoRoutes], // 合并路由
});
目录结构 转 对象结构 (vite工程)
采用 约定大于配置 的方式获取目录结构
应用示例:
- 需求
- 目录结构
- n1/n2文件:每个JS文件中的输出语句对应各自的文件名
- 实现
// 根目录: m.js// webpack 获取编译时态的目录结构: require.context//vite 获取编译时态的目录结构: import.meta.glob/** 获取bar目录下所有js模块* return: key: 模块路径, value: 动态导入语句* ./TempTestModule/bar/a/n1.js: () => import("/TempTestModule/bar/a/n1.js")*/
// const modules = import.meta.glob("./TempTestModule/bar/**/*.js");// 如果想同时获取bar目录和foo目录下所有的JS模块,可以用数组的形式
const modules = import.meta.glob(["./TempTestModule/bar/**/*.js", "./TempTestModule/foo/**/*.js"],{eager: true, // 不再使用动态导入,直接获取模块的导入结果import: "default", // 获取默认导出结果}
);
// console.log(modules);const result = {};for (const path in modules) {const moduleDefault = modules[path];// 去除路径中的 /反斜杠、 .点,以及删除数组中的第一项TempTestModule(顶端文件夹名)和最后一项 .js(文件后缀名)const matches = path.match(/[^\/\.]+/g).slice(1, -1);// console.log(path, matches);let current = result;for (let i = 0; i < matches.length; i++) {const key = matches[i];current[key] = current[key] || {};// 如果是数组的最后一项,直接赋值为导出结果if (i === matches.length - 1) {current[key] = moduleDefault;}current = current[key];}
}
// console.log(result);export default result;
// 根目录: index.html执行调用
<script type="module">import M from "./m.js";// 确保DOM加载完成后再执行document.addEventListener("DOMContentLoaded", () => {// 用 约定大于配置的方式在编译时态获取目录结构// 把TempTestModule目录下的整个 目录结构 转换为 对象结构 并输出打印语句M.bar.a.n1.m(); // bar/a/n1.jsM.bar.a.n2.m(); // bar/a/n2.jsM.bar.b.n1.m(); // bar/b/n1.jsM.bar.b.n2.m(); // bar/b/n2.jsM.foo.a.n1.m(); // foo/a/n1.jsM.foo.a.n2.m(); // foo/a/n2.jsM.foo.b.n1.m(); // foo/b/n1.jsM.foo.b.n2.m(); // foo/b/n2.js});
</script>