自动注册Vue组件【require.context】

5 篇文章 0 订阅

在Vue项目开发中,经常需要import或者export各种模块,当一个页面中组件很多时,我们可能会这样引入组件:

import A from 'components/A.vue'
import B from 'components/B.vue'
import C from 'components/C.vue'
import D from 'components/D.vue'

要是每加一个组件,都要写这么一句 import ,那岂不是很蛋疼,是否可以通过自动化引入呢?

答案是肯定有的,那就要使用 webpack 给我们提供的 require.context API:

require.context(directory, useSubdirectories, regExp)

它接收三个参数:

  • directory: 要查找的文件路径
  • useSubdirectories: 是否查找子目录
  • regExp: 要匹配文件的正则

比如我在根目录 src/components 文件夹下有 A.vueB.vueC.vueD.vue四个组件文件,那我就可以通过它获取所需要的信息:

const ctx = require.context('./src/components', false, /\.vue$/)

我们可以打印一下 ctx,看返回的是什么内容:

var map = {
	"./A.vue": "./src/components/A.vue",
	"./B.vue": "./src/components/B.vue",
	"./C.vue": "./src/components/C.vue",
	"./D.vue": "./src/components/D.vue"
};


function webpackContext(req) {
	var id = webpackContextResolve(req);
	return __webpack_require__(id);
}
function webpackContextResolve(req) {
	var id = map[req];
	if(!(id + 1)) { // check for number or string
		var e = new Error("Cannot find module '" + req + "'");
		e.code = 'MODULE_NOT_FOUND';
		throw e;
	}
	return id;
}
webpackContext.keys = function webpackContextKeys() {
	return Object.keys(map);
};
webpackContext.resolve = webpackContextResolve;
module.exports = webpackContext;
webpackContext.id = "./src/components sync recursive \\.vue$";

从打印结果可以看出,require.context执行后,返回一个方法 webpackContext,这个方法又返回一个__webpack_require__,__webpack_require__就相当于require或者import。

同时 webpackContext 还有两个静态方法 keys 与 resolve,一个 id 属性。

  • keys:返回匹配成功模块的名字组成的数组;
  • resolve:接受一个参数request,request为 ./src/components 文件夹下面匹配文件的相对路径,返回这个匹配文件相对于整个工程的相对路径;
  • id:执行环境的id,返回的是一个字符串,主要用在module.hot.accept,应该是热加载看下keys是作用。

这样一来,通过 ctx.keys() 我们可以得到匹配文件的相对路径数组:

["./A.vue", "./B.vue", "./C.vue", "./D.vue"]

基于以上数组,我们就可以封装一个自动引入组件的方法了,比如在 utils 文件夹下创建 componentsRegister.js 文件:

// 处理首字母大写 abc => Abc
function changeStr(str) {
    return str.charAt(0).toUpperCase() + str.slice(1);
}
/**
 * 自动注册组件
 */
export default {
  install (Vue) {
  	const requireComponent = require.context('./src/components/', false, /[A-Z]\w+\.(vue|js)$/)

    requireComponent.keys().forEach(fileName => {
        const config = requireComponent(fileName);
        const componentName = changeStr(
            fileName.replace(/^\.\/(.*)\.\w+$/, '$1')
        );
        Vue.component(componentName, config.default || config); // 动态注册该目录下的所有.vue文件
    })
  }
}

最后在入口文件 main.js 中导入封装好的文件,即可实现组件的自动化引入:

import Vue from 'vue'; // 引入vue
import componentsList from './utils/componentsRegister';
Vue.use(componentsList);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值