vite中import.meta.glob动态路由的疑问

最近通过博客学习了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')
}

当用其来进行路由引入的时候,由于需要在文件中进行判断是否注册为路由组件,所以在通过.then获得相应模块

//组件中
export default defineComponent({
  name: 'home',
  isRouter: true,//注册为路由
  setup() {
  }
})

//方法中
 const modules = import.meta.glob('../views/**/*.vue')
   for (const path in modules) {
    modules[path]().then((mod) => {
      const file = mod.default;
      if (!file.isRouter) return //判断
      router.addRoute({
        path: `/${file.name}`,
        name: `${file.name}`,
        component: file //then方法访问到的模块
      })
    })
  }

当通过遍历 modules 对象的 key并且.then后访问到了模块,后再用获取到的模块直接注册路由,这样会不会丧失路由的懒加载效果?
我一直在纠结如果不使用.then的话直接component:modules[key],就可以保留原始的路由懒加载格式,即component:()=>import('路径'),但使用.then后就直接变为了component:组件模块`(>﹏<)′

img

img


不会 在main.js全局配置 ,点击是触发(路径)才会请求数据--->

如果不好 可以采用这种


const modules = import.meta.glob("../views/**/**.vue")

let routerList: any = []

Object.keys(modules).forEach(key => {
  const nameMatch = key.match(/^\.\.\/views\/(.+)\.vue/)
  if (!nameMatch) return
  const indexMatch = nameMatch[1].match(/(.*)\/Index$/i)
  let name = indexMatch ? indexMatch[1] : nameMatch[1];
  // 首字母转小写 letterToLowerCase 首字母转大写 letterToUpperCase
  routerList.push({
    path: `/${(name[0].toUpperCase() + name.slice(1))}`,
    name: `${(name[0].toUpperCase() + name.slice(1))}`,
    component: modules[key]
  });
})
console.log(routerList, '===')

去vite的官方文档找线索, 发现vite升级到2.0的版本后, 多出一个方法, import.meta.glob, 可以动态引入路由, 一开始想着, 直接把后端传过来的用户页面权限路径放进这个方法里, 结果编译的时候报错, 参数不允许使用变量

没辙, 只能去翻一下vite的源码, 发现用的是typescript, 尝试改一下源码

把原来的注释掉, 把参数定义成any类型, 重新编译, 还是报错, 不晓得为什么, 改了没有效果, 没办法, 只能再去往下看源码, 发现他不止能接受一个页面地址, 还可以使用通配符, 知道这个, 我们就可以把项目中views下的文件都放进去, 然后再去判断用户拥有这个文件夹下面的哪些页面权限,

function addRouter(list) {
  const modules = import.meta.glob("./views/**.vue");
  for (const path in modules) {
    modules[path]().then((mod) => {
      const file = mod.default;
      if (list.map((a) => a.name).includes(file.name)) {
        router.addRoute({
          path: "/" + file.name,
          name: file.name,
          component: file,
        });
      }
    });
  }
}

拿到的modules是一个对象, 进行遍历, 然后等待回调拿到页面信息, 其中list是当前用户所拥有的页面信息, 进行比对, 如果为true就addRoute添加路由. 把代码写完之后我们再打包, 重新上传到服务器, 再访问项目站点, 我们就可以发现, 路由已经没问题了, 切换页面也是正常显示的.

但是还有一个缺点, 因为这个方法是个异步的方法, 路由还没及时添加进去, 因此在刷新页面的时候, 页面还是空白, 需要再点击一下菜单栏才能正常显示, 这个问题我暂时还没有解决方案, 不得不说, 使用新技术风险太大了, 很多意想不到的坑在等着你跳, 网上的资料又不全, 只能硬着头皮去尝试解决.