vue3 + vite使用addroute时接口返回数据导致component的问题

310 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

问题

接口返回数据导致component无法像正常路由那样使用component: () => import('view/xxx.vue')的方式引入文件

可以直接翻到底下看解决方法


详解

很多后台管理系统,路由都是通过请求获得,一般流程都是通过使用addroute处理接口返回的路由信息
vue3+vite中,动态路由component写法是

    router.addRoute({
        name: "demo",
        path: "/demo",
        component: () => import('view/demo.vue'),
    });

除了component属性,其他属性不需要做特殊处理

component属性,如果直接写成下例方法,这运行不会报错,但是打包后会找不到component属性中的文件,我们需要一个Vite支持的import.meta.glob方法来实现

// 这样写运行不会报错,但是打包后会有问题
const res = [ // 接口数据
    {
        name: "demo",
        path: "/demo",
        component: '/view/demo.vue',
    },
    ...
]
res.forEach(item => {
    item.component = getComponent(item.component)
    ...
})
/**
 * 处理component
 */
function getComponent(path) {
    return () => import(`../../${path}`)
}
...
res.forEach(item => {
    router.addroute(item)
})

解决方法

import.meta.glob方法

先看vite官网(点击跳转)中关于import.meta.glob的解释

Vite 支持使用特殊的 import.meta.glob 函数从文件系统导入多个模块:

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

以上将会被转译为下面的样子:

// vite 生成的代码
const modules = {
  './dir/foo.js': () => import('./dir/foo.js'),
  './dir/bar.js': () => import('./dir/bar.js')
}

你可以遍历 modules 对象的 key 值来访问相应的模块:

for (const path in modules) {
  modules[path]().then((mod) => {
    console.log(path, mod)
  })
}

匹配到的文件默认是懒加载的,通过动态导入实现,并会在构建时分离为独立的 chunk。如果你倾向于直接引入所有的模块(例如依赖于这些模块中的副作用首先被应用),你可以使用 import.meta.globEager 代替

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

所以,这样写就可以了~

// 看实际需求,这边举例就先引入所有view中的vue文件
const modules = import.meta.glob('../../view/**/*.vue')
const res = [ // 接口数据
    {
        name: "demo",
        path: "/demo",
        component: '/view/demo.vue',
    },
    ...
]

res.forEach(item => {
    // 通过key值找到 modules 中对应的属性,访问对应的模块
    item.component = modules[`../../${item.component}`]
    ...
})
...
res.forEach(item => {
    router.addroute(item)
})

end