当项目达到一定的规模时,路由会非常多,再都放在一个文件可读性就差点意思了,而路由模块化就易于阅读以及管理
文件目录:
方案一:通过import ‘fileName’ from "./file" 引入
在index.ts总文件中,只需要使用import ‘fileName’ from "./file"把每一个文件模块一个个引入,我们最终只需要导入所有模块的内容汇总到 index.js
中即可
import Module from "./module.ts";
import Module2 from "./module2.ts";
import Module3 from "./module3.ts";
const routes = {
Module,
Module2,
Module3
};
const router = createRouter({
history: createWebHistory(import.meta.env.VITE_PUBLIC_PATH),
routes
});
export default router;
优点:不会像一开始将所有文件堆在 index.js
中那么的烦乱了。
缺点:虽然可以解决,可以让路由配置和管理更清晰和便捷了,但是我们在 index.js
中会反复的进行 import ... from ...
导入所有配置的路由模块,模块一多那么这些的 import
语句也就越多!这是程序员能容忍的嘛?(内心:我就想写短的代码!!!)
方案二:自动导入,一劳永逸
思路:只需要拿到所有模块文件再导出即可,如下代码:
1.导入所有路由文件(不同构建工具略微不同)
/**
* 使用 require.context 去获取一个特定的上下文,主要用来实现自动化导入模块
* @param {String} param1 所以读取的文件的目录
* @param {Boolean} param2 是否遍历子目录
* @param {RegExp} param3 匹配文件的正则表达式
* @return {Function} 返回一个函数的对象,我们可以调用其 keys() 方法获取到所有匹配城中的文件名称组成的数组
*/
const moduleFiles = require.context('./modules', false, /\.ts$/);
注意:require.context 是 Webpack
提供的 API,如果是vite构建的项目需要用glob
//globEager已弃用
const moduleFiles = import.meta.globEager('./modules/*.js');
//js
let moduleFiles = import.meta.glob("./*.ts", { eager: true });
//ts
let moduleFiles: Record<
string,
{
[key: string]: any;
}
> = import.meta.glob("./*.ts", { eager: true });
2.获取所有文件数据处理
返回的moduleFiles是一个对象函数,log(moduleFiles)输出
对象导出的对象中有一个属性:default,可以获取到默认导出的所有内容
思路:把所有的文件数据获取到,整合到routes中
Object.keys(moduleFiles).map((ele: any) => {
const value = moduleFiles[ele].default || {};
// 我们判断导出的是不是数组,是则进行拓展解构
if (Array.isArray(value)) routes.push(...value);
else routes.push(value);
});
1.Object.keys(moduleFiles)把所有对象可遍历属性返回一个数组格式
2.map遍历数据,调用moduleFiles对象中每一个函数的default属性拿到我们导出的值
3.判断导出的值是否为数组,是扩展结构push到routes数组中,否直接加入
4.最终处理数据格式
完整代码
error.ts
// 错误页面路由
export default [
{
path: "/:pathMatch(.*)",
redirect: "/404"
},
{
path: "/404",
component: () => import("@/views/error-page/404.vue"),
meta: { title: "404", hidden: true }
},
{
path: "/403",
component: () => import("@/views/error-page/403.vue"),
meta: { title: "403", hidden: true }
},
{
path: "/401",
component: () => import("@/views/error-page/401.vue"),
meta: { title: "401", hidden: true }
}
];
index.ts
import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";
let routes: Array<RouteRecordRaw> = [
{
path: "/sso/auth",
redirect: "/",
component: () => import("@/views/page/index.vue")
...
}
];
/**
* 动态加载路由配置文件
* moduleFiles是一个函数,那么可以接受一个参数(string:文件的相对路径),
* 调用其从而获取到对应路径下的模块的导出对象导出的对象中有一个属性:default,可以获取到默认导出的所有内容
*/
let moduleFiles: Record<
string,
{
[key: string]: any;
}
> = import.meta.glob("./*.ts", { eager: true });
Object.keys(moduleFiles).map((ele: any) => {
const value = moduleFiles[ele].default || {};
// 我们判断导出的是不是数组,是则进行拓展解构
if (Array.isArray(value)) routes.push(...value);
else routes.push(value);
});
console.log(routes);
const router = createRouter({
history: createWebHistory(import.meta.env.VITE_PUBLIC_PATH),
routes
});
export default router;