如何自动引入Vuex中分割的Module

326 阅读2分钟

一般情况下,一个比较大或者复杂的vue前端项目,我们都会将store 分割成模块(module) ,这样避免了使用单一状态树,不易区分类别、不好维护、臃肿的问题。

今天在这里,我们并不想讨论分割模块具体如何实现,毕竟这是基础,我也不想老生常谈。我想在这里讨论的是如何自动获取modules里面的store模块,然后引入store中,而不必我们开发者自己去引入子store模块,然后声明到modules里。

假设我们的store模块如下图结构:

1719297609084.png

store中 index.js 的实现如下:

import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
import app from './modules/app'
import permission from './modules/permission'
import settings from './modules/settings'
import tagsView from './modules/tagsView'
import user from './modules/user'
Vue.use(Vuex)
const store = new Vuex.Store({
  modules: {
    app,
    permission,
    settings,
    tagsView,
    user
  },
  getters
})
export default store

里面分模块有app、permission、settings、tagsView、user,如果项目太大太复杂,指不定还有好多分模块需要引入,那该如何通过代码自动引入呢?

如果你的项目是基于webpack构建的Vue2项目,你可以通过下方代码实现:

实现一: 通过reduce循环模块

import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
Vue.use(Vuex)

const modulesFiles = require.context('./modules', true, /\.js$/)
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
  const value = modulesFiles(modulePath)
  modules[moduleName] = value.default
  return modules
}, {})

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

实现二: 通过 for in 循环模块

// 相同代码已省略

const modules = {}
const modulesFileLists = modulesFiles.keys()
for (const keyword in modulesFileLists) {
  let key = modulesFileLists[keyword]
  const moduleName = key.replace(/^\.\/(.*)\.\w+$/, '$1')
  const value = modulesFiles(key)
  modules[moduleName] = value.default
}

// 相同代码已省略

实现三: 通过 forEach 循环模块

// 相同代码已省略

const modules = {}
modulesFiles.keys().forEach(keyword => {
  const moduleName = keyword.replace(/^\.\/(.*)\.\w+$/, '$1')
  const value = modulesFiles(keyword)
  modules[moduleName] = value.default
});

// 相同代码已省略

如果你的项目是基于Vite构建的Vue2项目,你可以通过下方代码实现:

import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
Vue.use(Vuex)

const modulesFiles = import.meta.globEager('./modules/**/*.js')
const modules = {}
for (const key in modulesFiles) {
  modules[key.replace(/(\.\/modules\/|\.js)/g, '')] = modulesFiles[key].default
}

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

如果你的项目是基于Vite构建的Vue3项目,你可以通过下方代码实现:

import { createStore } from 'vuex'

const modulesFiles = import.meta.globEager('./modules/**/*.js')
const modules = {}
for (const key in modulesFiles) {
  modules[key.replace(/(\.\/modules\/|\.js)/g, '')] = modulesFiles[key].default
}

const store = createStore({
    modules, 
    getters
})
export default store