一、参考

  1. import.meta.glob 导入

二、import.meta.glob 介绍

2.1 import.meta.glob 的作用

  1. 匹配到的文件默认是懒加载的,通过动态导入实现,并会在构建时分离为独立的 chunk
  2. 类似于webpack的 require.context()

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'),
}

2.2 { eager: true } 一次引入所有

匹配到的文件默认是懒加载的,通过动态导入实现,并会在构建时分离为独立的 chunk。如果你倾向于直接引入所有的模块(例如依赖于这些模块中的副作用首先被应用),你可以传入 { eager: true } 作为第二个参数:

const modules = import.meta.glob('./dir/*.js', { eager: true })

2.3 Glob 导入注意事项

  • 这只是一个 Vite 独有的功能而不是一个 Web 或 ES 标准
  • 该 Glob 模式会被当成导入标识符:必须是相对路径(以 ./ 开头)或绝对路径(以 / 开头,相对于项目根目录解析)或一个别名路径(请看 resolve.alias 选项)。
  • Glob 匹配是使用 fast-glob 来实现的 —— 阅读它的文档来查阅 支持的 Glob 模式。
  • 你还需注意,所有 import.meta.glob 的参数都必须以字面量传入。你 不 可以在其中使用变量或表达式

三 遍历 import.meta.glob 文件系统

<template>
<a href="https://cn.vitejs.dev/guide/features.html#glob-import">import.meta.glob</a>
  <ul>
    <li @click="modulesAction">modulesAction</li>
    <li @click="modulesUrlAction">modulesUrlAction</li>
    <li @click="modulesStrAction">modulesStrAction</li>
  </ul>
</template>

<script>
// 这个方法 类似于 webpack 的 require.context()学习笔记
const modules = import.meta.glob('./cssModule/*')
/*****
 // vite 生成的代码
 const modules = {
  './dir/foo.js': () => import('./dir/foo.js'),
  './dir/bar.js': () => import('./dir/bar.js'),
}
 */
const modulesStr = import.meta.glob('./cssModule/*.vue', { as: 'raw' })
const modulesUrl = import.meta.glob('./cssModule/*.vue', { as: 'url' })

export default {
  mounted() {
  },
  methods: {
    modulesAction () {
      console.log('modules', modules)
      for (const path in modules) {
        console.log('modules[path]', modules[path])
        /*  modules[path]是一个promise引入文件函数
        modules[path]() 表示开始异步引入文件, */
        modules[path]().then(function (mod) {
          // console.log(arguments)
          console.log(path, mod)
          debugger
          // 如果是 scss 文件 或者 .module.css 文件,会编译 scss为css,然后转为 css module 对象
          // 如果引入的是Vue文件,就会编译 Vue文件,有 render函数,调用render 会生成一个 Vue实例对象
          if (mod.default.render) {
            const result = mod.default.render()
            console.log('result', result)
          }
        })
      }
    },
    modulesUrlAction () {
      console.log('modulesUrl', modulesUrl)
      for (const path in modulesUrl) {
        console.log('modules[path]', modules[path])
        modules[path]().then(function (mod) {
          // console.log(arguments)
          console.log(path, mod)
          debugger
          // 如果是 scss 文件 或者 .module.css 文件,会编译 scss为css,然后转为 css module 对象
          // 如果引入的是Vue文件,就会编译 Vue文件,有 render函数,调用render 会生成一个 Vue实例对象
          if (mod.default.render) {
            const result = mod.default.render()
            console.log('result', result)
          }
        })
      }
    },
    modulesStrAction () {
      console.log('modulesStr', modulesStr)
      for (const path in modulesStr) {
        console.log('modules[path]', modules[path])
        modules[path]().then(function (mod) {
          // console.log(arguments)
          console.log(path, mod)
          debugger
          // 如果是 scss 文件 或者 .module.css 文件,会编译 scss为css,然后转为 css module 对象
          // 如果引入的是Vue文件,就会编译 Vue文件,有 render函数,调用render 会生成一个 Vue实例对象
          if (mod.default.render) {
            const result = mod.default.render()
            console.log('result', result)
          }
        })
      }
    }
  }
}
</script>

四、根据文件名动态添加路由

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) {
    /* 
    const modules = import.meta.glob('./dir/*.js')
	  会转为
		const modules = {
      './dir/foo.js': () => import('./dir/foo.js'),
      './dir/bar.js': () => import('./dir/bar.js')
    }
    viteModules[path]()  表示已经开始执行加载了,没有实现懒加载
    */
    // 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

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐