自动导入+动态组件
Nuxt项目(Vite)
代码图
ts
import { defineAsyncComponent } from 'vue'
const componentMap = {}
for (const [path, defineComponent] of Object.entries(
import.meta.glob('@/components/home/module*.vue')
)) {
const id = parseInt(path.split('module')[1])
componentMap[id] = defineAsyncComponent(defineComponent)
}
import { defineAsyncComponent } from 'vue'
const componentMap = {}
for (const [path, defineComponent] of Object.entries(
import.meta.glob('@/components/home/module*.vue')
)) {
const id = parseInt(path.split('module')[1])
componentMap[id] = defineAsyncComponent(defineComponent)
}
vue
<component
:is="componentMap[item.showType]"
:settings="item.settings"
></component>
<component
:is="componentMap[item.showType]"
:settings="item.settings"
></component>
自动导入模块
js
//import.meta.glob用于实现基于模式的文件导入,类似于文件系统的模式匹配
//例如 *.vue来一次性导入多个文件。这通常用于动态加载模块或组件。
import.meta.glob('/src/components/**/*.vue')
//import.meta.glob用于实现基于模式的文件导入,类似于文件系统的模式匹配
//例如 *.vue来一次性导入多个文件。这通常用于动态加载模块或组件。
import.meta.glob('/src/components/**/*.vue')
提示
- import.meta.glob返回一个函数,该函数接受一个字符串参数,该参数是一个模式,用于匹配文件路径。
- 返回的函数返回一个对象,该对象的键是匹配的文件路径,值是一个函数,
该函数返回一个Promise
,该Promise解析为模块的导出。 - import.meta.globEager返回一个对象,该对象的键是匹配的文件路径,值是模块的导出。
- import.meta.globEager返回的对象是静态的,不会在运行时更新。
import.meta.glob原理
模式定义
:你指定一个匹配模式,如 import.meta.glob('../components/*.vue'),来匹配所有在 components 目录下的 Vue 组件。编译时转换
:在构建过程中,基于这个模式,构建工具(如 Vite)会分析并识别出符合模式的所有文件。生成动态导入语句
:对于每个匹配的文件,import.meta.glob 会生成一个返回 Promise 的函数,该函数在调用时会动态导入相应的模块。惰性加载
:由于每个导入都是通过 Promise 实现的,模块只会在你实际调用这个函数时才被加载。这使得初始包大小可以保持较小,同时允许按需加载更多的内容
常见例子
js
// 一次性导入多个文件
const modules = import.meta.glob('../components/*.vue')
//导入某个文件
const module = import.meta.glob('../components/HelloWorld.vue')
//导入某个文件夹下的所有文件
const modules = import.meta.glob('../components/*.vue')
//导入某个文件夹下的所有文件夹下的所有文件
const modules = import.meta.glob('../components/**/*.vue')
// 一次性导入多个文件
const modules = import.meta.glob('../components/*.vue')
//导入某个文件
const module = import.meta.glob('../components/HelloWorld.vue')
//导入某个文件夹下的所有文件
const modules = import.meta.glob('../components/*.vue')
//导入某个文件夹下的所有文件夹下的所有文件
const modules = import.meta.glob('../components/**/*.vue')
js
const modules = import.meta.glob('./components/**/*.vue')
for (const path in modules) {
modules[path]().then((mod) => {
// 处理每个模块
})
}
const modules = import.meta.glob('./components/**/*.vue')
for (const path in modules) {
modules[path]().then((mod) => {
// 处理每个模块
})
}
js
const modules = import.meta.globEager('./components/**/*.vue')
for (const path in modules) {
const component = modules[path]
// 处理每个模块
}
const modules = import.meta.globEager('./components/**/*.vue')
for (const path in modules) {
const component = modules[path]
// 处理每个模块
}
js
const components = import.meta.glob('./components/**/*.vue')
Object.entries(components).forEach(([path, defineAsyncComponent]) => {
const componentName = path
.split('/')
.pop()
.replace(/\.\w+$/, '')
app.component(componentName, defineAsyncComponent())
})
const components = import.meta.glob('./components/**/*.vue')
Object.entries(components).forEach(([path, defineAsyncComponent]) => {
const componentName = path
.split('/')
.pop()
.replace(/\.\w+$/, '')
app.component(componentName, defineAsyncComponent())
})
js
const routes = Object.keys(import.meta.glob('../views/*.vue')).map((path) => {
return {
path: path.replace(/..\/views|\.vue/g, ''),
component: () => import(path)
}
})
const routes = Object.keys(import.meta.glob('../views/*.vue')).map((path) => {
return {
path: path.replace(/..\/views|\.vue/g, ''),
component: () => import(path)
}
})
Vue项目(Webpack)
代码
js
const modulesFiles = require.context(
'@/views/pc/homeSet/components/module',
false,
/\.vue$/
)
const components = modulesFiles.keys().reduce((components, modulePath) => {
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
components[moduleName] = () =>
import(`@/views/pc/homeSet/components/module/${moduleName}.vue`)
return components
}, {})
const modulesFiles = require.context(
'@/views/pc/homeSet/components/module',
false,
/\.vue$/
)
const components = modulesFiles.keys().reduce((components, modulePath) => {
const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
components[moduleName] = () =>
import(`@/views/pc/homeSet/components/module/${moduleName}.vue`)
return components
}, {})
vue
computed: { currentComponent() { return
components[`module${specialTypes[this.moduleObj.showType] ||
this.moduleObj.showType}`]; } }
computed: { currentComponent() { return
components[`module${specialTypes[this.moduleObj.showType] ||
this.moduleObj.showType}`]; } }
自动导入模块
require.context() 是一个Webpack特有的特性,用于创建一个上下文,通过它可以告诉Webpack在构建过程中应该动态地从一个目录中包含哪些文件。这个功能通常在需要动态地加载一组模块时使用,例如自动加载某个目录下的所有测试文件或组件。这样做可以减少手动导入每个文件的需要,简化代码并提高可维护性。
require.context用法
- 基本用法
js
var context = require.context(
directory,
(useSubdirectories = false),
(regExp = /^\.\//)
)
var context = require.context(
directory,
(useSubdirectories = false),
(regExp = /^\.\//)
)
- 参数说明
directory
:说明需要检索的目录useSubdirectories
:是否检索子目录regExp
: 匹配文件的正则表达式
- 返回值 require.context() 返回一个(require)
函数
,这个函数可以接受一个参数:请求的文件的路径。这个函数有三个属性:
html
resolve:是一个函数,它返回请求被解析后得到的模块id
keys:是一个函数,它返回一个数组,包含所有可能被上下文模块处理的模块的路径
id:是执行此上下文模块的模块id
resolve:是一个函数,它返回请求被解析后得到的模块id
keys:是一个函数,它返回一个数组,包含所有可能被上下文模块处理的模块的路径
id:是执行此上下文模块的模块id