用vite动态导入vue的路由配置

        在Vue应用中,通过路由可以实现不同页面之间的切换,同时也可以实现页面之间的传参和控制页面的显示与隐藏。但是我们在开发的过程中,会发现在路由配置中的路由配置和我们的项目结构高度重复,在我们修改页面文件结构时非常的麻烦与复杂,这时候,如果可以动态的导入路由,就可以大大提示我们项目的可维护性。

        我们在开发中会经常听见一句话,约定大于配置,路由的动态导入也是这句话应用的一种,我们这里动态导入路由模仿了在uniapp进行小程序开发的页面配置文件,要求有以下几点:

  1. 所有的页面都必须配置到/src/pages文件夹下;
  2. 所有的页面文件层级必须是/src/pages/页面文件夹名称/;
  3. 所有的页面文件中必须有page.ts作为配置文件和index.vue作为页面入口文件;

结构展示如下:

page.ts文件展示:

//home的page.ts
export default {
  title: '首页',
  menuOrder: 1,
  childrens: [
    `../pages/homechildren`
  ]
}
//homechildren的page.ts
export default {
  title: '首页的子组件',
  menuOrder: 1,
  isChild: true,
}
//login的page.ts
export default {
  title: '登录',
  menuOrder: 2
}

        此时我们要通过vite的函数import.meta.glob()和import()扫描pages文件夹动态生成路由,代码如下:

//路由配置文件
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'

const pages = import.meta.glob('../pages/**/page.ts', {
  eager: true,
  import: 'default'
})

const components = import.meta.glob('../pages/**/index.vue')

const getChildRoutes = async (childrens: string[]) => {
  const res = [];

  for (const item of childrens) {
    const pageModule = await import(`${item}/page.ts`);
    const componentModule = await import(`${item}/index.vue`);

    const routePath = item.replace('../pages/', '').replace('/page.ts', '') || '/';
    const name = routePath.split('/').filter(Boolean).join('-') || 'index';

    res.push({
      path: routePath,
      name,
      component: componentModule.default,
      meta: pageModule.default
    });
  }

  return res;
};

const routes = Object.entries(pages).filter(([path, meta]: [string, any]) => !meta.isChild).map(([path, meta]: [string, any]) => {
  const compPath = path.replace('page.ts', 'index.vue')
  path = path.replace('../pages', '').replace('/page.ts', '') || '/';
  const name = path.split('/').filter(Boolean).join('-') || 'index';

  return {
    path,
    name,
    component: components[compPath],
    meta: meta,
    children: !!meta.childrens ? getChildRoutes(meta.childrens) : []
  } as RouteRecordRaw
})

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

//路由重定向
router.beforeEach((to, from, next) => {
  if (to.path === '/') {
    next('/home')
  } else if (!routes.some(route => route.path === to.path)) {
    next('/home')
  } else {
    next()
  }
  
})

export {
  router
}

 效果展示:

路由对象展示:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星极天下第一

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值