Vite-自动生成Vue路由

1,318 阅读1分钟

大部分Vue项目使用路由都是在src/router/index.ts中增加routes的配置,如下图

image.png

我们可以看到routes的配置重复的代码非常多,且当我们项目页面开始变多时,routes里的元素也会越来越多。

自动生成路由

当我们在页面目录下新建页面文件时,自动帮我们完成routes的配置。

src下新建views目录(项目的页面)

image.png

每个页面有个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;

总结

image.png

生成的routes结构符合路由配置,并且也大大减少了我们手动增加代码的工作量。

10月30日---补充带子路由的逻辑

目录结构

image.png


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结构

image.png