由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。下面介绍两种模块化开发方式:
参考文档:https://vuex.vuejs.org/zh-cn/modules.html
Module
Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
例如,store 文件下 有 index.js, a.js, b.js
a.js
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
export default moduleA
b.js
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
export default moduleB
index.js
import moduleA from './a.js'
import moduleB from './b.js'
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
命名空间方式
默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。
如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true
的方式使其成为命名空间模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。
例如,还是store 文件下 有 index.js, a.js, b.js
a.js
const moduleA = {
namespaced: true,
state: {
name:'lyc',
aget: '20'
},
mutations: {
name: (state, name) => state.name = name,
age: (state, age) => state.age = age,
},
actions: {
rename(context, name){
context.commit('name', name)
},
renage(context, age){
context.commit('age', age)
}
},
getters: { ... }
}
export default moduleA
b.js
const moduleB = {
namespaced: true,
state: {
type:'xxx',
},
mutations: {
type: (state, type) => state.type = type,
},
actions: { ... },
getters: { ... }
}
export default moduleB
index.js
import moduleA from './a.js'
import moduleB from './b.js'
const store = new Vuex.Store({
modules: {
moduleA: moduleA,
moduleB: moduleB
}
})
带命名空间的绑定函数
当使用 mapState, mapGetters, mapActions 和 mapMutations 这些函数来绑定命名空间模块时,写起来可能比较繁琐: methods: { test1(){ this.$store.dispatch(‘rename’, ‘LYC’) }, test2(){ this.$store.dispatch(‘reage’, ‘3’) } }, computed: { …mapState({ name: state => state.moduleA.name, age: state => state.moduleA.age, type: state => state.moduleB.type, }) },
对于这种情况,你可以将模块的空间名称字符串作为第一个参数传递给上述函数,这样所有绑定都会自动将该模块作为上下文。于是上面的例子可以简化为: methods: { …mapActions(‘moduleA’,[‘rename’,’reage’]), test1(){ this.rename(‘LYC’) }, test2(){ this.reage(‘3’) } }, computed: { …mapState(‘moduleA’,[‘name’,’age’]), …mapState(‘moduleB’,[‘type’]), },
而且,你可以通过使用 createNamespacedHelpers
创建基于某个命名空间辅助函数。它返回一个对象,对象里有新的绑定在给定命名空间值上的组件绑定辅助函数:
import { createNamespacedHelpers } from 'vuex'
const { mapState, mapActions } = createNamespacedHelpers('moduleA')
export default {
computed: {
// 在 `moduleA` 中查找
...mapState(['name','age'])
}
}
其他辅助函数同 ...mapState
参考案例:我的仓库