六、Vuex - Module
Module 模块
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 的状态
模块的局部状态
- 模块内部的 mutation、getter 的第一个参数为模块的局部状态对象
- 模块内部的 action中, 局部状态通过 context.state 暴露, 根节点点状则为 content.rootState
- 模块内部的 getter, 根节点的状态会作为第三个参数暴露出来
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'] } } } } } });
在带命名空间的模块内访问全局内容
- 使用全局的 state 和 getter, rootState 和 rootGetters 会作为第三和第四参数传入 getter, 也会通过 context 对象的属性传入action
- 分发和提交全局命名空间的action、mutation, 将 { root: true } 作为第三参数传给 dispatch 或 commit 即可
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
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' ]) } }
相关推荐
CSCCockroach 2020-09-15
lbPro0 2020-07-05
MrSunOcean 2020-06-21
lylwanan 2020-06-14
Callmesmallpure 2020-05-31
ShaLiWa 2020-05-25
墨龙吟 2020-04-24
MrSunOcean 2020-04-24
H女王范儿 2020-04-22
lbPro0 2020-04-16
ShaLiWa 2020-02-29
ShaLiWa 2020-01-17
MrSunOcean 2020-01-03
lbPro0 2020-01-01
H女王范儿 2019-12-29