vuex 动态加载modules文件下的所有JS文件

Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:

const moduleA = {
    
    
  state: {
    
     ... },
  mutations: {
    
     ... },
  actions: {
    
     ... },
  getters: {
    
     ... }
}

const moduleB = {
    
    
  state: {
    
     ... },
  mutations: {
    
     ... },
  actions: {
    
     ... }
}

const store = new Vuex.Store({
    
    
  modules: {
    
    
    a: moduleA,
    b: moduleB
  }
})

store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态

在项目中一般都会将modules模块根据业务需求分成多个js文件,每个js文件模块有各自的内容,如

modules
|__ user.js
|__ app.js
...

user.js
const user = {
    
    
    state: {
    
    
        ...
    },
    mutations: {
    
    
        ...
    },
    actions: {
    
    
        ...
    }
}
export default user

那么在创建store的时候就需要将这些模块文件一一导入,如果模块少这样写还可以接受,如果模块很多的情况下这样就不够优雅,那有没有方法可以将modules下的模块动态加载进来呢。

import user from 'user.js'
import app from 'app.js'
...

const store = new Vuex.Store({
    
    
  modules: {
    
    
  user,
  app,
  ....
});

最近接触到了一个函数require.context()生成上下文模块,它包含对该目录中所有模块的引用。

用法:
接收三个参数

require.context(directory, useSubdirectories, regExp)

directory:需要检索的目录
useSubdirectories:是否检索子目录
regExp: 匹配文件的正则表达式,一般是文件名

返回参数
require.context()返回一个require 函数,该函数接受一个参数。
该require函数有三个属性:resolve 、keys、id

  • resolve: 是一个函数,他返回的是被解析模块的id 。
  • keys: 也是一个函数,他返回的是一个数组,该数组是由所有可能被上下文模块解析的请求对象组成,也就是文件路径组成的数组。
  • id:上下文模块的id。

require.context()具体用法参考:// https://webpack.js.org/guides/dependency-management/#requirecontext

这里可以利用keys属性,获取到modules文件夹下的所有js文件路径组成的数组,通过这个数组就可以拿到模块里的内容,最后将这些内容和文件名组成一个modules对象。
具体代码如下:

文件结构
store
|__modules
|   |__ user.js
|   |__ app.js
|   |...
|__index.js


// 以下是index.js内容

import Vue from 'vue';
import Vuex from 'vuex';
import getters from './getters';

Vue.use(Vuex);

// 获取moudules文件下所有js文件
const context = require.context('./modules', false, /\.js$/);
// context.keys() 返回匹配成功模块的名字组成的数组
const modules = context.keys().reduce((modules, modulePath) => {
    
    
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1');
  // 通过context(key)导出文件内容。在文件中时通过export.default导出的,所以后边加.default
  const fileModule = context(modulePath);
  modules[moduleName] = fileModule.default;
  return modules;
}, {
    
    });

const store = new Vuex.Store({
    
    
  modules,
  getters
});
export default store;

猜你喜欢

转载自blog.csdn.net/weixin_45032067/article/details/125648050