一个使用 Vue2
构建的应用越来越复杂,随着而来的是应用状态的复杂;这时就需要根据功能或组件将 VueX
的 store
进行模块化。
应用的初始化除了大体框架搭建、功能目录的划分、工具的封装外等,更加抽象化的操作都是需要随着开发慢慢推进。大部分起始创建的 store
中,无需进行模块的划分,只需要提供创建 store
实例的 state\getters\actions\mutations
参数。
当将应用状态进行模块的划分,最简单地莫不过是如下
// 目录结构
// store
// -- index.js
// |-- modules
// -- cart.js
// -- products.js
// |-- info
// -- actions.js
// -- getters.js
// -- index.js
// -- mutations.js
// -- state.js
// index.js
import Vue from 'vue'
import Vuex from 'vuex'
import cart from './modules/cart'
import products from './modules/products'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
cart,
products,
},
})
// cart.js/products.js
const state = {}
const getters = {}
const actions = {}
const mutatios = {}
export default {
namespaced: true,
state,
getters,
actions,
mutatios,
}
手动导入指定模块只适用于模块数量不多的情况;可以使用 webpack
提供的 require.context
方法,遍历指定文件目录并可加载指定文件
// 在 store\index.js 同级下创建 modules.js 文件
// 指定导入当前 modules 文件目录中的 js 文件
const _files = require.context('./modules', true, /\.js$/)
const modules = _files.keys().reduce((modules, path) => {
if (path.indexOf('.js')) {
const name = path.replace(/^\.\/|.js$/g, '')
modules[name] = _files(path).default
return modules
}
return modules
}, {})
export default modules
// 在 store\index.js 中引入 modules.js 文件
import Vue from 'vue'
import Vuex from 'vuex'
import modules from './modules'
Vue.use(Vuex)
export default new Vuex.Store({
state: {},
mutations: {},
actions: {},
modules,
})
<template>
<div>
<span>{{ state1 }}</span>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
computed: {
...mapState('cart', ['state1']),
},
}
</script>
随着模块数量增加和操作的复杂,单个 js
文件不能再满足单个模块的复杂度;此时可以将模块拆分为目录结构,目录中 js
文件划分为 index、state、getters、types、actions、mutations
。
// 指定导入当前 modules 文件目录中的 js 文件
const _files = require.context('./modules', true, /\.js$/)
// 过滤指定名称的文件
const _ignoreFiles = ['states', 'getters', 'actions', 'types', 'mutations']
const modules = _files.keys().reduce((modules, path) => {
if (path.indexOf('.js') && !_ignoreFiles.filter((file) => path.includes(file)).length) {
const name = path.replace(/^\.\/|.js$/g, '').replace(/\/index$/g, '')
modules[name] = _files(path).default
return modules
}
return modules
}, {})
export default modules
replace(/\/index$/g, '')
是把一个模块由多个文件组成的情况,在使用时指定路径简化为模块文件夹路径即可。
export default {
data() {},
computed: {
// ...mapState('info/index', ['state1'])
...mapState('info', ['state1'])
}
}