本文是:Vue工程化封装实践系列第三篇,相关系列其他文章如下:
- axios封装+ vue-bus全局事件通信
- vue防止表单重复提交,请求队列取消方法
- 组件自动注册+vuex模块自动载入
- vuex数据的本地化存储
- 路由分模块自动载入
- 权限指令封装
- 更简洁的代码:render函数
- mixin混入
- 全局过滤器
- directive自定义指令
- echarts resize窗口自适应
- vue动画高级
- less全局变量抽离+自定义多环境打包
组件自动注册
实现思路
目录结构如下:

代码
componnets/loader.js
// 将components下面的全部vue文件注册为全局组件,组件引用统一按照文件名首字母大写引用
// 将首字母大写 confirmModal 转为 ConfirmModal
function changeStr(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
export function ComponentsLoader(Vue) {
/*
webpack的核心Api,建议大家掌握,大有用处
require.context(arg1,arg2,arg3)
arg1 - 读取文件的路径
arg2 - 是否遍历文件夹子目录
arg3 - 匹配文件名的正则
*/
const requireComponent = require.context('.', false, /\.vue$/);
console.log('requireComponent.keys():', requireComponent.keys()); // 打印加载到的文件名称
requireComponent.keys().forEach(fileName => {
const config = requireComponent(fileName); // 加载组件
const componentName = changeStr(
fileName.replace(/^\.\//, '').replace(/\.\w+$/, '') // ./child1.vue => Child1
);
console.log('componentName:', componentName);
Vue.component(componentName, config.default || config); // 动态注册该目录下的所有.vue文件
});
}
main.js
// 其他不相关代码省略
import { ComponentsLoader } from './views/components/loader';
Vue.use(ComponentsLoader);
xxx.vue 业务代码
<template>
<div :class="$style.messageRoute">
... 此处省略 ...
<ConfirmModal :confirmModalObj="confirmModalObj" :msg="confirmModalObj.msg" @iot-confirm="delConfirm" desc=""></ConfirmModal>
</div>
</template>
<script>
// 此处不需要引入了
// import confirmModal from './components/confirmModal'
export default {
name: 'contentArea',
components: {
// confirmModal,
},
data() {
return {
... 此处省略 ...
}
}
}
vuex模块自动载入

代码
store/modules/count.js
const moduleA = {
state: { count: 0 },
mutations: {
increment(state) {
state.count++;
}
}
};
export default moduleA;
store/loader.js
/**
* 将/store/modules/下的js 文件全部导入vuex中,而无需手动增加,模块名称以文件名命名
*/
const files = require.context('./modules', false, /\.js$/);
const modules = {};
files.keys().forEach(key => {
modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default;
});
console.log('vuex-modules:', modules);
export default modules;
store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
import modules from './loader.js'; // 导入文件
Vue.use(Vuex);
const store = new Vuex.Store({
modules
});
export default store;
main.js
import Vue from 'vue';
import App from './App.vue';
import store from './store/index.js';
... 省略其他代码 ...
new Vue({
render: h => h(App),
store
}).$mount('#app');
xxx.vue 业务代码
<template>
<div>
... ...
</div>
</template>
<script>
export default {
name: 'Main',
mounted() {
this.$store.commit('increment'); // 调用方法
}
};
</script>