一、为什么需要模块化
前面我们讲到的例子都在一个状态树里进行,当一个项目比较大时,所有的状态都集中在一起会得到一个比较大的对象,进而显得臃肿,难以维护。为了解决这个问题,Vuex允许我们将store分割成模块(module),每个module有自己的state,mutation,action,getter,甚至还可以往下嵌套模块,下面我们看一个典型的模块化例子
const moduleA = {
state: {....},
mutations: {....},
actions: {....},
getters: {....}
}const moduleB = {
state: {....},
mutations: {....},
actions: {....},
getters: {....}
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // moduleA的状态
store.state.b // moduleB的状态
二、模块的局部状态
模块内部的mutation和getter,接收的第一参数(state)是模块的局部状态对象,rootState
const moduleA = {
state: { count: 0},
mutations: {
increment (state) {
// state是模块的局部状态,也就是上面的state
state.count++
}
},
getters: {
doubleCount (state, getters, rootState) {
// 参数 state为当前局部状态,rootState为根节点状态
return state.count * 2
}
},
actions: {
incremtnIfOddRootSum ( { state, commit, rootState } ) {
// 参数 state为当前局部状态,rootState为根节点状态
if ((state.cont + rootState.count) % 2 === 1) {
commit('increment')
}
}
}
}
三、命名空间(这里一定要看,不然有些时候会被坑)
上面所有的例子中,模块内部的action、mutation、getter是注册在全局命名空间的,如果你在moduleA和moduleB里分别声明了命名相同的action或者mutation或者getter(叫some),当你使用store.commit(‘some’),A和B模块会同时响应。所以,如果你希望你的模块更加自包含和提高可重用性,你可以添加namespaced: true的方式,使其成为命名空间模块。当模块被注册后,它的所有getter,action,mutation都会自动根据模块注册的路径调用整个命名,例如:
const store = new Vuex.Store({
modules: {
account: {
namespaced: true,
state: {...}, // 模块内的状态已经是嵌套的,namespaced不会有影响
getters: { // 每一条注释为调用方法
isAdmin () { ... } // getters['account/isAdmin'] },
actions: {
login () {...} // dispatch('account/login')
},
mutations: {
login () {...} // commit('account/login')
},
modules: { // 继承父模块的命名空间
myPage : {










