你是否也烦透了每写一个页面就要编写一次route路由配置?不如跟我一起写一个自动导入的工具函数,挂载时执行,解决一大烦恼!
实现效果:
新建页面自动注册,无需重复编写路由配置!
初始化项目
创建项目
使用 vite
新建 vue3
项目
yarn create vite
pure@MacBook-Pro Developer % yarn create vite
yarn create v1.22.15
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 🔨 Building fresh packages...
success Installed "create-vite@2.7.2" with binaries:
- create-vite
- cva
✔ Project name: … autoload-router
✔ Select a framework: › vue
✔ Select a variant: › vue-ts
Scaffolding project in /Users/pure/Documents/Developer/autoload-router...
Done. Now run:
cd autoload-router
yarn
yarn dev
✨ Done in 82.90s.
这里我选的是 vue-ts
啪!很快啊,不到一分钟就创建好了!(估计是有缓存,看你网速了)
新建 router, views, layouts 文件夹
router 放路由配置文件(当然是自动加载的脚本)
views 一般存放页面具体的内容
layouts 存放布局相关,通常是整体结构
先创建页面和布局,方便测试路由
views 新建两个文件夹 admin, member 对应所有后台和前台页面
admin 和 member 底下又可以细分页面,现在模拟admin 和 member 各有一个 home 页面:两个文件下分别创建 home 文件夹,在 home 文件夹下新建index.vue
作为页面。
layouts 新建两个 .vue
文件,admin, member 这是两个平台下的布局
这个规范来自于:》》》
为 Vue 挂载路由
安装 vue-router 4.x
yarn add vue-router@4.X
yarn add @types/vue-router
创建编写 router 的地方
cd src/router
touch index.ts # 路由入口文件
touch route.ts # 自定义路由
touch autoload.ts # 自动导入路由
在 index 中导入两种路由来源配置
import { createRouter, createWebHistory } from "vue-router";
import autoLoadRoutes from "./autoload";
import customRoutes from "./route";
const router = createRouter({
history: createWebHistory(),
routes: [...autoLoadRoutes,...customRoutes],
});
export default router;
创建默认页面
删除自带 App.vue template, 只放一个<router-view>
就可以了
在 views
文件夹中创建 index.vue
,作为全局首页
<template>
<div>
<h2>index page</h2>
<router-link to="admin">Go To admin page</router-link>
<br/>
<router-link to="member">Go To member page</router-link>
</div>
</template>
自定义路由中添加 首页
export default [
{
path: "/",
component: () => import("../views/index.vue"),
},
];
修改 main.js 将 router 从外部引入后挂载到 vue
import { createApp } from "vue";
import App from "./App.vue";
import router from './router/index'
const app = createApp(App)
app.use(router);
app.mount("#app");
大概是这样,随意啦
创建好之后那我们现在来写路由配置文件!
编写自动导入路由脚本
自动导入 layouts
在router/autoload.ts中导入所有
layouts`文件夹下的组件,作为父级路由
// router/autoload.ts
import _ from "lodash";
const layoutRoutes = import.meta.globEager("../layouts/*.vue");
// 生成路由配置
const getRoutes = () => {
const routes = _.toPairs(layoutRoutes).map(([file, module]) => {
// file: ../layouts/admin.vue
// 默认以 ’../layouts/‘ 后面作为路由的 path 或 name
const name = file.match(/\.\.\/layouts\/(?<name>.+?)\.vue/i)
?.groups?.name;
return {
path: "/" + name,
name: name,
component: module.default,
};
});
return routes;
};
export default getRoutes();
这种结构
测试都是可以的
自动导入 views
既然layouts
导入完成了,现在将views
看做children
,以文件夹名字匹配views
的父路由
因为views
分为admin
和member
,其下面又有很多页面,所以将匹配
// 生成页面路由
const getViewRoutes = (filename: string, component: any): RouteRecordRaw => {
const name = filename.match(/\.\.\/views\/(?<name>.+?)(index)?\.vue/i)?.groups
?.name;
return {
path: "/" + name,
name: name,
component: component.default,
children: [],
};
};
// 查询 layoutsRoute 下所有子路由
const getChildRoutes = (layoutRoute: RouteRecordRaw) => {
const routes: RouteRecordRaw[] = [];
_.toPairs(viewRoutes).map(([filename, module]) => {
// 对每个 views 查询是否属于传入的 layout 路由
if (filename.includes(layoutRoute.name as string)) {
routes.push(getViewRoutes(filename, module));
}
});
return routes;
};
// 为每个 layouts 路由添加子路由
const getRoutes = () => {
const routes = _.toPairs(layoutRoutes).map(([file, module]) => {
const layoutRoute = getLayoutRoutes(file, module);
layoutRoute.children = getChildRoutes(layoutRoute);
return layoutRoute;
});
return routes;
};
效果
附代码:
MyCodebak/Web/vue/autoload-router at master · sunzehui/MyCodebak (github.com)