
import {createStore} from 'vuex';
const moduleA = {
state: {
name: 'a'
}
};
const moduleB = {
state: {
name: 'b'
}
};
const store = createStore({
modules: {
a: moduleA,
b: moduleB
}
});
console.log(store.state.a.name); // a
console.log(store.state.b.name); // b
嵌套模块

import {createStore} from 'vuex';
const store = createStore({
state: {
counter: 0
},
getters: {
counter10times(state) {
return state.counter * 10;
}
},
modules: {
a: {
state: {aName: 'A·a'},
aGetters: {
aFirstName(state) {
return state.aName.split('·')[0];
}
},
modules: {
c: {
state: {cName: 'C·c'},
getters: {
cFirstName(state) {
return state.cName.split('·')[0];
}
}
}
}
},
b: {
state: {bName: 'B·b'},
getters: {
bFirstName(state) {
return state.bName.split('·')[0];
},
bNewName(state, getters, rootState, rootGetters) {
// 访问局部state
const {bName} = state;
// 访问全局state
const {a: {c: {cName}}} = rootState;
// 访问局部getters
const {bFirstName} = getters;
// 访问全局getters
const {cFirstName} = rootGetters;
return `${bName} ${bFirstName} ${cName} ${cFirstName}`;
}
}
}
}
});
// 子模块的state通过子模块路径访问
console.log(store.state.a.c.cName);
// 子模块的getters都注册到了全局,在store.getters下面直接能访问到
console.log(store.getters.bNewName);
多模块,commit mutation和dispatch action的示例
模块可以提交其他模块的mutation,从而改变其他的模块的状态;模块也可以触发其他模块的action
import {createStore} from 'vuex';
const store = createStore({
state: {
counter: 0
},
mutations: {
increaseCounter(state) {
state.counter++;
}
},
modules: {
a: {
state: {aName: 'A·a'},
mutations: {
changeAName(state) {
state.aName = 'A-a';
}
},
actions: {
callChangeCNameAsync({dispatch}) {
// 触发其他模块的action
setTimeout(() => {
dispatch('changeCNameAsync');
}, 500);
}
},
modules: {
c: {
state: {cName: 'C·c'},
mutations: {
changeCName(state, payload) {
state.cName = `C-c-${payload.suffix}`;
}
},
actions: {
changeCNameAsync({commit, rootState}) {
setTimeout(() => {
// 提交其他模块的mutation,mutation是全局的
commit('increaseCounter');
// 提交局部模块的mutation
commit('changeCName', {
suffix: rootState.counter
});
}, 500);
}
}
},
}
},
b: {
state: {bName: 'B·b'},
mutations: {
changeBName(state) {
state.bName = 'B-b';
}
}
}
}
});
// 全局的commit
store.commit('increaseCounter');
console.log(store.state.counter); // 1
// 子模块mutation注册到全局了
store.commit('changeCName', {suffix: '123'});
console.log(store.state.a.c.cName); // C-c-123
// 子模块commit其他模块的mutation
store.dispatch('changeCNameAsync');
setTimeout(() => {
console.log(store.state.a.c.cName); // C-c-2
}, 1000);
// 子模块dispatch其它模块的action
store.dispatch('callChangeCNameAsync');
setTimeout(() => {
console.log(store.state.a.c.cName); // C-c-3
}, 1500);
- 默认情况下,所有模块的getters、mutations和actions都是注册到全局的,这样如果多个子模块的getters、mutations和actions中有同名时候,会导致覆盖,引起问题。因此通常我们需要给子模块加命名空间。
2.给子模块加命名空间的方式是给子模块加namespaced属性并赋值为true。
- [ ]加了命名空间后,访问state的方式不变(因为默认state也不是注册到全局的)
- 访问getters时候需要加命名空间前缀
- 如果访问模块自身子模块的getters、提交mutations、触发actions时候,只需要加相对路径前缀,不需要加自身命名空间前缀
- 例如模块a访问其子模块c时候,不需要加’a/c’前缀,只需要’c’就可以了。
看下多模块(包含嵌套模块情况)时候访问state和getters的示例:
import {createStore} from 'vuex';
const store = createStore({
state: {
counter: 0
},
getters: {
counter10times(state) {
return state.counter * 10;
}
},
modules: {
a: {
namespaced: true,
state: {aName: 'A·a'},
getters: {
aFirstName(state) {
return state.aName.split('·')[0];
}
},
modules: {
c: {
namespaced: true,
state: {cName: 'C·c'},
getters: {
cFirstName(state) {
return state.cName.split('·')[0];
}
}
}
}
},
b: {
namespaced: true,
state: {bName: 'B·b'},
getters: {
bNewName(state, getters, rootState, rootGetters) {
// 局部state
const bName = state.bName.split('·')[0];
// 其他模块的getter
const cFirstName = rootGetters['a/c/cFirstName'];
// 其他模块的state
const aName = rootState.a.aName;
return `${bName} ${cFirstName} ${aName}`;
}
}
}
}
});
// getters命名空间
console.log(store.getters['b/bNewName']); // B C A·a
// 子节点state仍然是通过节点路径访问
console.log(store.state.a.c.cName); // C·c
看下在使用了命名空间的多模块的提交mutations和触发actions
import {createStore} from 'vuex';
const store = createStore({
state: {
counter: 0
},
mutations: {
increaseCounter(state) {
state.counter++;
}
},
modules: {
a: {
namespaced: true,
state: {aName: 'A·a'},
mutations: {
changeAName(state) {
state.aName = 'A-a';
}
},
actions: {
callChangeCNameAsync({dispatch}) {
// 触发子模块的action,是相对于自身的路径,不需要加a前缀
setTimeout(() => {
dispatch('c/changeCNameAsync');
}, 500);
}
},
modules: {
c: {
namespaced: true,
state: {cName: 'C·c'},
mutations: {
changeCName(state, payload) {
state.cName = `C-c-${payload.suffix}`;
}
},
actions: {
changeCNameAsync({commit, rootState}) {
setTimeout(() => {
// 提交其他模块的mutation,mutation是全局的
commit('increaseCounter', null, {root: true});
// 提交局部模块的mutation,不需要加前缀
commit('changeCName', {
suffix: rootState.counter
});
}, 500);
}
}
},
}
},
b: {
namespaced: true,
state: {bName: 'B·b'},
mutations: {
changeBName(state) {
state.bName = 'B-b';
}
}
}
}
});
// 全局的commit
// 注意加了命名空间之后,提交根模块的mutation和触发根模块的action时候,都需要加上{root: true}的选项
store.commit('increaseCounter', null, {root: true});
console.log(store.state.counter); // 1
// 子模块mutation注册到全局了
store.commit('a/c/changeCName', {suffix: '123'});
console.log(store.state.a.c.cName); // C-c-123
// 子模块commit其他模块的mutation
store.dispatch('a/c/changeCNameAsync');
setTimeout(() => {
console.log(store.state.a.c.cName); // C-c-2
}, 1000);
// 子模块dispatch其它模块的action
store.dispatch('a/callChangeCNameAsync');
setTimeout(() => {
console.log(store.state.a.c.cName); // C-c-3
}, 1500);