vite2、vue-router4下动态路由的动态导入的实现

随着Vue3、Vite2的正式版发布,越来越多的人开始使用这些新技术来提高开发效率了。最近在尝试使用Vue3、Vite2、element-plus、Typescript做个后台管理Demo,遇到根据后台数据生成菜单路由动态导入的问题。

以下是代码核心逻辑:

...

// 生成路由数据, menus是获取后台菜单数据
const routes = generateRoutes(menus)

// router.addRoute 在路由实例router上增加路由
router.addRoute({
    name: 'main', path: '/main', component: () => import('../components/Main.vue'), meta: { name: '首页' },
    children: routes
})

...

// 生成main的子路由数据
function generateRoutes(menus: any[]) {
    let routes: any[] = []
    menus.forEach((menu: any) => {
        routes.push({ name: menu.menuId, path: menu.menuUrl, component: () => import('../components/' + menu.componentPath + '.vue'), meta: { name: menu.menuName } })
        return routes
    })
}

在本地开发测试过程中,点击菜单能正常访问到对应的页面,但是打包部署到服务器后,就出现动态导入的错误,如下图:


本地开发没有问题,是因为vite支持动态加载当前访问的页面,但在打包的时,vite会根据项目中import来打包文件,上面代码import('../components/' + menu.componentPath + '.vue'),由于是运行时才能知道对应页面,vite在打包时并不知道应该打包哪些对应的文件,所以就出现上面的错误。要解决这个问题,就需要提前把路由菜单对应的文件打包到项目当中。


vite2中提供了一个Glob 导入功能,匹配到的文件默认是懒加载的,通过动态导入实现,并会在构建时分离为独立的 chunk。

修改后的代码核心逻辑:

...

// 生成路由数据, menus是获取后台菜单数据
const routes = generateRoutes(menus)

// router.addRoute 在路由实例router上增加路由
router.addRoute({
    name: 'main', path: '/main', component: () => import('../components/Main.vue'), meta: { name: '首页' },
    children: routes
})

...

// 使用Glob导入
let modules = import.meta.glob('../components/**/*.vue');

// 生成main的子路由数据
function generateRoutes(menus: any[]) {
    let routes: any[] = []
    menus.forEach((menu: any) => {
        // routes.push({ name: menu.menuId, path: menu.menuUrl, component: () => import('../components/' + menu.componentPath + '.vue'), meta: { name: menu.menuName } })
        // 使用Glob方式
        routes.push({ name: menu.menuId, path: menu.menuUrl, component: modules['../components/' + menu.componentPath + '.vue'], meta: { name: menu.menuName } })
        return routes
    })
}

使用Glob这种方式后,vite打包时,就会将路径对应的文件打包到项目中了,就解决了上面出现的那个错误。


import.meta.glob('../components/**/*.vue')将匹配../components/**/*.vue这个路径下所有的vue文件打包,会存在打包一些没必要打包的文件,可以通过修改路径表达式来限制打包哪些文件,比如:

../components/**/*list.vue 打包路径下文件名为list结束的vue文件

../components/**/(*list.vue|test.vue) 打包路径下文件名为list结束的vue文件以及test.vue文件

14 赞
领支付红包
文章内容仅供参考!欢迎加入技术开发交流QQ群:36479297