一、参考

  1. Vue Router4.x 动态路由
  2. Vite import.meta.glob

二、问题描述

最近在学习Vite + Vue3,使用Vite创建项目工程,将Vue3的一个知识点作为一个页面,但是发现随着学习的知识点增多,页面也越来越多,每个页面都要配置Vue-router 的路由信息,很繁琐,因此想能否根据文件夹的目录来配置路由。

考虑到webpack 有 require.context()功能可以读取文件夹的文件 ,猜想vite肯定也提供了类似的功能

三、import.meta.glob 从文件系统导入多个模块

参考 Vite import.meta.glob

const modules = import.meta.glob('./dir/*.js')

// 会转为

const modules = {
  './dir/foo.js': () => import('./dir/foo.js'),
  './dir/bar.js': () => import('./dir/bar.js')
}

3.1 如何遍历引入的文件系统

const viteModules = import.meta.glob('./dir/*.js');
// 重点: import.meta.glob 不支持动态加载, 下面的例子是不支持的
// const viteModules = import.meta.glob('@/pages/'+moduleStr+'/*.vue');
console.log(viteModules)
const viteModuleArr = [];
for (const path in viteModules) {
	// path 的值为 /src/pages/vite/echartsPage.vue
	const mode = viteModules[path]
	console.log(path, mod)
}

注意:import.meta.glob 不支持动态加载, 下面的代码是不支持的

// 重点: import.meta.glob 不支持动态加载, 下面的例子是不支持的
const moduleStr = 'myvite'
const viteModules = import.meta.glob('@/pages/'+moduleStr+'/*.vue');

router.addRoute()实现动态路由

  1. 创建 Vue-router 路由实例
import { createRouter, createWebHashHistory, Router } from 'vue-router'
import Welcome from '@/pages/Welcome.vue'
import SubRouterLayout from '@/components/SubRouterLayout.vue'
import { loadDynamicPage as loadVue3Page } from './dynamicAddVue3Routes'
import { loadDynamicPage as loadVitePage } from './dynamicAddViteRoutes'
import { loadDynamicPage as loadVue3AdvancePage } from './dynamicAddVue3AdvanceRoutes'

const routerOptions: RouterOptions = {}

// 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。
routerOptions.history = createWebHashHistory(),

// routerOptions.routes: Object[] = []
routerOptions.routes = [
  {
    path: '/',
    name: 'welcome',
    component: Welcome,
    // redirect: '/basicIndex',
    meta: {
      title: '欢迎 Vite + typescript + Vue3 + Vue4-router + Pinia 全家桶学习'
    }
  },
  {
    path: '/vue3',
    name:'vue3',
    component: SubRouterLayout,
    children: [
      {
        path: '',
        name: 'Vue3基础导航',
        component: () => import('@/pages/vue3/index.vue'),
        meta: {
          title: 'vue3 setup 语法基础学习'
        }
      },
      {
        path: 'setupPage',
        component: () => import('@/pages/vue3/setupPage.vue'),
        meta: {
          title: 'setup 与 option配置混合使用(不推荐)'
        }
      },
    ]
  },
  {
    path: '/vite',
    name:'vite',
    component: SubRouterLayout,
    children: [
      {
        path: '',
        name: 'vite 打包工具',
        component: () => import('@/pages/vite/index.vue'),
        meta: {
          title: 'vite 打包工具'
        }
      },
    ]
  },
  {
    path: '/vue3Advance',
    name:'vue3Advance',
    component: SubRouterLayout,
    children: [
      {
        path: '',
        name: 'vue3 高级应用',
        component: () => import('@/pages/vue3Advance/index.vue'),
        meta: {
          title: 'vite 打包工具'
        }
      },
    ]
  }
]
const router: Router = createRouter(routerOptions)
// 动态添加路由地址
loadVue3Page(router)
loadVitePage(router, 'vite')
loadVue3AdvancePage(router, 'vue3Advance')

console.log(router.getRoutes())
export default router

备注:由于import.meta.glob 不支持动态加载,因此,要导入三个动态加载目录的文件

  1. 创建dynamicAddVue3Routes.ts根据目录动态加载路
import { de } from 'element-plus/es/locale';
import { Router } from 'vue-router';

export const loadDynamicPage = function (router: Router, moduleStr = 'vue3'): void {
  /* 
  https://router.vuejs.org/zh/guide/advanced/dynamic-routing.html
  动态路由的例子:
  router.addRoute({ path: '/about', component: About })
  */
  const routerObj: Router = router;
  // const modules = import.meta.glob('./dir/*.js')
  const viteModules = import.meta.glob('@/pages/vue3/*.vue');
  // 重点: import.meta.glob 不支持动态加载
  // const viteModules = import.meta.glob('@/pages/'+moduleStr+'/*.vue');
  console.log(viteModules)
  const viteModuleArr = [];
  for (const path in viteModules) {
    // path 的值为 /src/pages/vite/echartsPage.vue
    // console.log(path, mod)
    const length = path.lastIndexOf('/');
    const filename = path.substring(length + 1).split('.')[0];
    const routeOption = {
      // path: '/vite/' + filename,
      path: `/${moduleStr}/${filename}`,
      component:  viteModules[path] // 是将vue文件解析为组件的对象
    }
    routerObj.addRoute(routeOption);
    // router.getRoutes():获取一个包含所有路由记录的数组。
    // console.log('routerObj.getRoutes', routerObj.getRoutes());
    /* 
    重点:
    如果新增加的路由与当前位置相匹配,就需要你用 router.push() 或 router.replace() 来手动导航,才能显示该新路由。
    */
    routerObj.replace(routeOption.path)
  }  
};

备注:** 如果新增加的路由与当前位置相匹配,就需要你用 router.push() 或 router.replace() 来手动导航,才能显示该新路由。**

Logo

前往低代码交流专区

更多推荐