Callmesmallpure 2019-12-01
Vuex 允许将 store 分割成模块(module), 每个模块拥有自己的state、mutation、action、getter甚至是嵌套子模块, 从上至下进行同样方式的分割。分割的好处是让代码更加清晰, 易于维护管理.
// A 模块 const moduleA = { state: {}, getters: {}, mutations: {}, actions: {} } // B 模块 const moduleB = { state: {}, getters: {}, mutations: {}, actions: {} } const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } }); // 访问独立模块的状态 store.state.a // 访问 moduleA 的状态 store.state.b // 访问 moduleB 的状态
const moduleA = { getters: { getCount (state, getters, rootState) { // state 局部状态 // 局部 getters, // rootState 根节点状态 return state.count + rootState.count; } }, mutations: { increment (state) { state.count++; // state 模块的局部状态 } }, actions: { increment ({ state, commit, rootState }) { // state 局部状态 // rootState 根节点状态 commit('increment'); } } }
默认情况下, 模块内部的 action、mutation、getter 是注册在全局命名空间的, 这样使得多个模块能够对同一mutation或action作出响应
如果希望你的模块具有更高的封装和复用性, 你可以通过天剑 namespaced: true 的方式使其成为带命名空间的模块。
当模块被注册后, 所有 getter、action及mutation 都会自动根据模块注册的路径调整命名。
const store = new Vuex.Store({ modules: { account: { namespaced: true, // 模块内容 sstate: {}, getters: { inAdmin () {} // getters['account/isAdmin'] }, mutations: { login () {} // commit('account/login') }, actions: { login () {} // dispatch('account/login') }, // 嵌套模块 modules: { // 继承父模块的命名空间 myPage: { state: {}, getters: { profile () {} // getter['account/profile'] } }, // 进一步嵌套命名空间 posts: { namespaced: true, state: {}, getters: { popular () {} // getter['account/posts/popular'] } } } } } });
modules: { foo: { namespaed: true, getters: { someGetter (state, getters, rootState, rootGetters) { getters.someOther // 'foo/someOther' rootGetters.someOhter // 'someOther' } }, actions: { someAction ({ dispatch, commit, getters, rootGetters }) { dispatch('someOtherAction') // 'foo/someOhterAction' dispatch('someOtherAction', null, { root: true }) // 'someOhterAction' 派发根节点的 action commit('someMutation') // 'foo/someMutation' commit('someMutation', null, { root: true }) // 'someMutation' 提交根节点的 mutation } } } }
action: { someAction: { root: true, // 将注册到全局中 handler () {} } }
当使用 mapState、mapGetters、mapActions、mapMutations时需要注意
// 方式一: 统一编写 computed: { ...mapState({ a: state => state.some.nested.module.a, b: state => state.some.nested.module.b }) }, methods: { ...mapActions([ // this['some/nested/module/foo']() 'some/nested/module/foo', 'some/nested/module/bar' ]) } // 方式二: 将模块的空间名称作为第一个参数,自动绑定模块上下文 computed: { ...mapState('some/nested/module', { a: state => state.a, b: state => state.b }) }, methods: { ...mapActions('some/nested/module', { 'foo', // this.foo() 'bar' // this.bar() }) } // 方式三: 通过 createNamespacedHelpers 创建基于某个命名空间辅助函数 import { createNamespacedHelpers } from 'vuex' const { mapState, mapAction } = createNamespacedHelpers('some/nested/module'); export default { computed: { ...mapState({ a: state => state.a, b: state => state.b }) }, methods: { ...mapActions([ 'foo', 'bar' ]) } }