项目中经常会使用到批量导入,这会帮助减少相似代码的编写
并且它还很多使用场景:
- 在组件内引入多个子组件
- 在main.js中批量引入注册全局组件
- 批量导入路由文件批量注册
- 引入vuex的module
一、require.context
(1)如果项目是基于webpack构建的,就可以使用require.context来实现批量导入
此函数传入三个参数:
- 搜索的目录
- 表示是否搜索其子目录
- 匹配文件的正则表达式
require.context('./test', false, /\.js$/);
// 批量导入test文件夹下的js文件,不考虑其子目录
(2)require.context导出一个函数,此函数有一个属性:keys
keys也是一个函数,它返回一个数组
(3)示例
3.1 示例一:
新建一个test文件夹,里面有三个文件
a.js 里有console.log('a')
b.js 里有console.log('b')
c.js 里有console.log('c')
平常引入方式:
import './test/a'
import './test/b'
import './test/c'
批量引入方式:
function importAll(r: any) {
r.keys().forEach(r)
}
importAll(require.context('./test', false, /\.js$/))
3.2 示例二: vue3项目批量注册全局组件
const app = createApp(App)
const module = require.context('./components', false, /\.vue$/)
module.keys().forEach((fileName) => {
// 组件实例
const comInstance = module(fileName).default || module(fileName)
// 组件实例name属性作为组件名称
const comName = comInstance.name
// 全局组件注册
app.component(comName, comInstance)
})
注:
module(fileName).default 返回的是Es6规范暴露的内容(如:export default)
module(fileName) 返回的是CommonJs规范暴露的内容(如:module.exports)
二、import.meta.glob
(1)如果项目是基于vite构建的,就可以使用import.meta.glob来实现批量导入
此函数传入二个参数
- 搜索的目录
- 配置对象
{ eager: true }置是否直接引入所有的模块
{ import: 'default' }配置是否加载默认导出。
(2)示例
2.1 示例一:
新建一个test文件夹,里面有三个文件
a.js 里有console.log('a')
b.js 里有console.log('b')
c.js 里有console.log('c')
const modules = import.meta.glob('./test/*.js');
以上将会被转译为下面的样子:并不能直接导入
// vite 生成的代码
const modules = {
'./test/a.js': () => import('./test/a.js'),
'./test/b.js': () => import('./test/b.js'),
'./test/c.js': () => import('./test/c.js'),
}
当然,可以遍历 module 对象的 key 值来访问相应的模块
for (const path in modules) {
modules[path]().then((mod) => {
console.log(path, mod)
})
}
增加 { eager: true } 配置,在上面编译的基础上,增加import直接导入
const modules = import.meta.glob('./test/*.js', {eager: true});
2.2 示例二:vue3项目批量注册全局组件
import { defineAsyncComponent, createApp } from 'vue'
const app = createApp(App)
// 获取components路径任意文件夹下的 index.vue 文件
const modules = import.meta.glob('./components/*/index.vue')
// 遍历获取到的组件模块
for (const [key, value] of Object.entries(modules)) {
// 组件名称
const componentName = key.split('/')[2]
// 通过 defineAsyncComponent 异步导入指定路径下的组件
app.component(componentName, defineAsyncComponent(value))
}