vite路由自动加载[动态路由]

1,661 阅读1分钟

vite路由

前言

项目中的页面过多,或者要做一些可配置的路由加载的时候,人工的配置路由就显得麻烦, 所以自动加载就来了

假设我们目前的页面目前是这样的

src/views/My/index.vue

那我们就可以去匹配views目录下,符合*/index.vue的组件作为路由

webpack自动加载

通过 require.context实现

const views = require.context('../views/', true, /index.vue$/);

导出的方法有 3 个属性: resolve, keys, idresolve一个函数,它返回请求被解析后得到的模块 id。 keys 也是一个函数,它返回一个数组,由所有可能被上下文模块处理的请求组成。 id 上下文模块里面所包含的模块 id. 它可能在你使用 module.hot.accept 的时候被用到

这里只用到 keys,返回搜索到的数组,遍历组成最终的路由集合

views.keys().forEach((key) => {
    let $route = views(key).default;
    let routerName = $route.name;
    let routerTitle = $route.title;
    let componentPath = $route.__file.replace(/^src//i, '');
    routes.push({
        path: routerName === 'Home' ? '/' : `/${routerName}`,
        name: routerName,
        title: routerTitle || routerName,
        component: () => import(
            /* webpackChunkName: "[request]" */
            `../${componentPath}`)
        ,
    })
});

挂载路由

Vue.use(VueRouter);

vite自动加载

通过import.meta.glob实现

const views = import.meta.glob(`../views/*/index.vue`, { eager: true })

eager参数

匹配到的文件默认是懒加载的,通过动态导入实现,并会在构建时分离为独立的 chunk。如果你倾向于直接引入所有的模块(例如依赖于这些模块中的副作用首先被应用),你可以传入 { eager: true } 作为第二个参数:

两种方式匹配到页面之后的处理方式都是相同的,生成最终的路由集合即可

import { createRouter, createWebHistory } from 'vue-router'

// 路由集合
const routes = []

const views = import.meta.glob(`../views/*/index.vue`, { eager: true })

// 动态加载路由
for (const componentPath in views) {
    const module: any = views[componentPath]
    const match: Array<any> = componentPath.match(/../views/(\w+)/) || []
    /// 匹配到的路由名称
    const routerName = match[1]
    if (routerName) {
        // 找到example的组件,并加载
        const $component = module.default
        const routerTitle = $component.title
        const title = routerTitle || routerName
        routes.push({
            path: routerName === 'Home' ? '/' : `/${routerName}`,
            name: routerName,
            title,
            component: $component
        })
    }
}

const router = createRouter({
    history: createWebHistory(),
    routes
})


export default router
    

main.js

const app = createApp(App)

import router from './router'

app.use(createPinia()).use(router)