大部分Vue项目使用路由都是在src/router/index.ts中增加routes的配置,如下图
我们可以看到routes的配置重复的代码非常多,且当我们项目页面开始变多时,routes里的元素也会越来越多。
自动生成路由
当我们在页面目录下新建页面文件时,自动帮我们完成routes的配置。
src下新建views目录(项目的页面)
每个页面有个page.ts文件用去设置页面的meta属性
// page.ts
export default {
title: "登录页面",
};
自动生成路由逻辑
在src/router/index.ts中书写逻辑
import { createRouter, createWebHistory } from "vue-router";
// 读取views下的page.ts文件
const pages = import.meta.glob("../views/**/page.ts", {
eager: true,
import: "default",
});
// 读取views下的index.vue文件
const pageComponents = import.meta.glob("../views/**/index.vue");
const routes = Object.entries(pages).map(([pagePath, meta]) => {
const path = pagePath.replace("../views", "").replace("/page.ts", "") || "/";
const name = path.split("/").filter(Boolean).join("-") || "index";
const component = pagePath.replace("page.ts", "index.vue");
return {
name,
path,
component: pageComponents[component],
meta,
};
});
const router = createRouter({
routes,
history: createWebHistory(),
});
export default router;
总结
生成的routes结构符合路由配置,并且也大大减少了我们手动增加代码的工作量。
10月30日---补充带子路由的逻辑
目录结构
import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";
const EMPTY_STRING = "";
const PAGE_TS = "page.ts";
const INDEX_VUE = "index.vue";
const INDEX = "index";
const getFileDeepth = (path: string) => (path.match(/\//g) || []).length;
const pageComponents = import.meta.glob("../views/**/index.vue");
const pages = import.meta.glob("../views/**/page.ts", {
eager: true,
import: "default",
});
const pageEntries = Object.entries(pages);
// 根据文件目录的层级找到子页面和子路由页面
const subPages = pageEntries.filter(([pagePath]) => getFileDeepth(pagePath) < 4); // 子页面
const pageChildren = pageEntries.filter(([pagePath]) => getFileDeepth(pagePath) > 3); // 子路由
const getComponentPath = (pagePath: string) => pagePath.replace(PAGE_TS, INDEX_VUE);
// 只实现了一层children的情况
const getChildren = (name: string) => {
return pageChildren
.map(([pagePath, meta]) => {
if (pagePath.includes(`${name}\/`)) {
const path = pagePath.replace(`../views/${name}`, EMPTY_STRING).replace("/page.ts", EMPTY_STRING);
const childName = path.substring(1);
const componentPath = getComponentPath(pagePath);
return {
path,
name: childName,
component: pageComponents[componentPath],
meta,
};
}
})
.filter(Boolean);
};
const routes: RouteRecordRaw[] = subPages.map(([pagePath, meta]) => {
const path: string = pagePath.replace("../views", EMPTY_STRING).replace("/page.ts", EMPTY_STRING) || "/";
const name = path.substring(1) || INDEX;
const componentPath = getComponentPath(pagePath);
const children = getChildren(name);
return {
path,
name,
component: pageComponents[componentPath],
meta,
children,
};
});
const router = createRouter({
routes,
history: createWebHistory(),
});
export default router;
生成的routes结构