vue3 + vite 同步/异步批量加载路由

vue3vue-routervite
2023-10-19 13:45:55

路由在前端开发当中很常见,频繁配置也是一项比较劳累的工作。自动化注入路由的开发模式,可以大大减少开发的时间。本文借助vite的import.meta.glob对文件进行全局加载,这种方式大大提高开发效率。

同步加载模式

先看看完整的代码

复制代码
const modules = import.meta.glob('../../views/**/*.vue', { eager: true, });
export const childrenRouteModuleList: RouteRecordRaw[] = [];

Object.keys(modules).forEach((file) => {
    // @ts-ignore
    const component = modules[file].default || {};
    const route = component.route
    if (route) {
        const path = toLower((file.match(/^.*?views(.*?).vue$/) || [])[1] || "") // 生成路由path

        // route meta 塞入默认的中文名称
        route.meta = route.meta || {}
        route.meta.title = route.meta.title || route.cname

        component.name = component.name || path.split("/").join("")

        const _route = {
            name: component.name,
            path: path,
            component,
            ...route,
        }

        childrenRouteModuleList.push(_route)
    }
});

const modules = import.meta.glob('../../views/**/*.vue', { eager: true, });

这种加载方式可以一次性加载所有的vue组件,但是很多情况下这个页面可能不是我们需要的页面。这个时候需要进行一些过滤。

过滤不必要的文件

指定特定文件名为入口页面

const modules = import.meta.glob('../../views/**/index.vue', { eager: true, });
例如这种写法,只有index.vue的页面被加载进来

在文件当中定义一个标识,用于识别是否为路由文件

ts 复制代码
  defineOptions({
      route: {
        meta: {
        }
      }
  })

然后在循环操作当中,读取这个标识来过滤文件。

复制代码
Object.keys(modules).forEach((file) => {
    // @ts-ignore
    const component = modules[file].default || {};
    const route = component.route
    if (route) {
        // ... 如果route 存在,则定义一些信息
        // route meta 塞入一些信息
        route.meta = route.meta || {}
        route.meta.title = route.meta.title || route.cname
    }
});

同步方式比较好的地方是,我们在页面当中,直接进行定义一些路由信息,没有必要再操作单独的路由文件。不好的地方在于,打包之后,会将vue文件打包到一块,使得首次加载页面的时间拉长。

异步的方式

上边批量加载的函数去掉{ eager: true, }这个配置,就变成异步加载了。

由于异步模块不会直接返回一个组件的原始信息,二是类似()=> import('xxx.vue')这样的形式返回,我们再用defineOptions的形式去单文件定义信息变得困难。这样以来如果需要自定义路由就有点困难了。这个时候,可以提供自定义路由的方式,来进行一些没办法实现的内容。

示例代码如下

↓ 会员用户可见内容 ↓
您暂无权限阅读此内容😴,请先破解或登录并低成本开通本站会员(很实惠)

路由当中使用

js 复制代码
export const RootRoute: RouteRecordRaw = {
    path: '/',
    name: 'Root',
    redirect: PageEnum.BASE_HOME,
    meta: {
        title: 'Root',
    },
    component: LAYOUT,
    children: childrenRouteModuleList,
}

export const basicRoutes = [
    RootRoute,
    // ... 其它路由文件导入
];


const router = createRouter({
  history: createWebHistory(),
  routes: basicRoutes as unknown as RouteRecordRaw[],
  scrollBehavior(to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition
    } else {
      return { top: 0 }
    }
  },
});