使用场景
当项目中出现很多客制化的组件,且组件数量较为庞大,且会根据不同的产品需求,加载不同的组件,就会出现很多对于当前产品无用的组件也一并加载,造成不必要的压力。故而,可根据后端或者前端单独维护的配置项文件就行组件的纯动态引入
技术点:require.context
什么是require.context
一个 webpack 的 api ,通过该函数可以获取一个上下文,从而实现工程自动化(遍历文件夹的文件,从中获取指定文件,自动导入模块)。
在前端工程中,如果一个文件夹中的模块需要频繁引用时可以使用该中方式一次性引入
具体使用讲解
-
参数介绍
参数 | 类型 | 说明 |
directory | String | 默认指定的需要进行动态加载相对应组件的默认路径(可使用vue.config.js中进行指定的@开头的路径配置) |
useSubdirectories | Boolean | 是否编辑文件的子目录 |
regExp | RegExp | 匹配文件的规则 |
-
定义示例
表示读取/views/components目录下以.vue结尾的文件
const _component = require.context(
"@/views/components", // 需要查找的文件路径
false, // 是否查找子目录
/\.vue$/ // 正则匹配 以 .vue结尾的文件
)
//console.log(_component)回参示例模拟
//var map = {
// './A.vue':'views/components/A.vue',
// './B.vue':'views/components/B.vue',
// './C.vue':'views/components/C.vue',
//}
//console.log(_component.keys())回参示例模拟
//["./A.vue", "./B.vue", "./C.vue"]
![](https://i-blog.csdnimg.cn/blog_migrate/a9d219f1655f15158d37e7a0915c8ab5.jpeg)
-
回参详解
>> resolve {Function} 接收一个参数request,request为test文件夹下面匹配文件的相对路径, 返回这个匹配文件相对于整个工程的相对路径
>> keys {Function} 返回匹配成功模块的名称组成的数组
>> id {String} 执行环境的id,返回的是一个字符串,主要用在module.hot.accept,应该是热加载?
这三个都是作为函数的属性(注意是作为函数的属性,函数也是对象,有对应的属性)
-
回参处理示例
/**
* resultComps 为自定义的存储对应的组件实例的容器
* _component(fileName).default 为获取对应的组件的实例内容,方便后续直接使用
*/
let resultComps = {}
_component.keys().forEach((fileName) => {
resultComps[fileName] = _component(fileName).default;
});
//使用(可以直接在vue的<template></template>中的component标签中进行加载调用),如下:
<component
:is="resultComps('fileName')"
></component>
完整示例(封装方法)
下述完整示例中,针对加载特定的.vue文件以及/Home/index.vue两种方式进行了兼容处理
前者传参为文件名称
后者为index.vue外层对应的目录名称
两者的区别之处将通过 [区别] 字眼进行标注
/**
* <该方法支持针对特定目录下,直接为.vue的文件进行获取>
* @param {String} fileName 文件名称
*/
const dynamicLoadRequireComponentsDemoA = (fileName) => {
try {
const resultComps = {};
let requireComponent = require.context(
"@/views/workbench/commonComponents", // 需要查找的文件路径
false, // 是否查找子目录[区别]
/\.vue$/ // 正则匹配 以 .vue结尾的文件[区别]
)
requireComponent.keys().forEach((k) => {
resultComps[k] = requireComponent(k).default;
});
return resultComps[fileName];
} catch (error) {
console.log("动态载入模板解析异常");
}
};
/**
* <该方法可以针对定向目录下的目录中的index.vue进行动态获取加载>
* @param {String} fileName 目录名称
*/
const dynamicLoadRequireComponentsDemoB = (fileName) => {
try {
const resultComps = {};
let requireComponent = require.context(
"@/views/workbench/commonComponents",
true, //[区别]
/\/index\.vue$///[区别]
)
requireComponent.keys().forEach((k) => {
resultComps[k.replace(/^\.\//, '').replace(/\/index\.vue$/, '')] =
requireComponent(k).default; //[区别]
});
return resultComps[fileName];
} catch (e) {
throw new Error(`动态载入模板解析异常 :${e}`);
}
}
/**
* 使用动态加载组件的方法
* 在对应的.vue文件中先引入(import)该方法
*/
<template>
<div>
<component
:is="dynamicLoadRequireComponents('A.vue')"
></component>
</div>
</template>