💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
## **一:Module** >[success]Vuex 允许我们将 store 分割成**模块(module)**。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块 ~~~ const moduleA = { state: { ... }, mutations: { ... }, actions: { ... }, getters: { ... } } const moduleB = { state: { ... }, mutations: { ... }, actions: { ... } } const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } }) store.state.a // -> moduleA 的状态 store.state.b // -> moduleB 的状态 ~~~ ## **二:模块的局部状态** 对于模块内部的 mutation 和 getter,接收的第一个参数是**模块的局部状态对象**。 ~~~ const moduleA = { state: { count: 0 }, mutations: { increment (state) { // 这里的 `state` 对象是模块的局部状态 state.count++ } }, getters: { doubleCount (state) { return state.count * 2 } } } ~~~ 同样,对于模块内部的 action,局部状态通过`context.state`暴露出来,根节点状态则为`context.rootState`: ~~~ const moduleA = { // ... actions: { incrementIfOddOnRootSum ({ state, commit, rootState }) { if ((state.count + rootState.count) % 2 === 1) { commit('increment') } } } } ~~~ 对于模块内部的 getter,根节点状态会作为第三个参数暴露出来: ~~~ const moduleA = { // ... getters: { sumWithRootCount (state, getters, rootState) { return state.count + rootState.count } } } ~~~ ## **命名空间** **默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的** ## 如果希望你的模块具有更高的**封装度**和**复用性**,使用命名空间后可以在模块内部嵌入子模块,并且无需修改代码,只需要在模块中设置 `namespaced: true`即可。(例如在工单模块下嵌入预约单等等) ~~~ const store = new Vuex.Store({ modules: { trade: {//工单模块 namespaced: true, // 模块内容(module assets) state: { ... }, // 模块内的状态已经是嵌套的了,使用 `namespaced` 属性不会对其产生影响 getters: { isAdmin () { ... } // -> getters['trade/isAdmin'] }, actions: { login () { ... } // -> dispatch('trade/login') }, mutations: { login () { ... } // -> commit('trade/login') }, // 嵌套子模块 modules: { // 继承父模块的命名空间 schedule: { //预约单模块 state: { ... }, getters: { profile () { ... } // -> getters['trade/profile'] } }, // 进一步嵌套命名空间 posts: { namespaced: true, state: { ... }, getters: { popular () { ... } // -> getters['trade/posts/popular'] } } } } } }) ~~~ ## **在带命名空间的模块内访问根模块** * 如果想要访问根模块的`state`和`getter`,只需要在第三和第四个参数传入`rootState`和`rootGetters`即可。 * 如果想触发根模块的`action`和`mutation`,只需要将`{ root: true }`作为第三参数传给`dispatch`或`commit`即可。 ~~~ modules: { foo: { namespaced: true, getters: { // 在这个模块的 getter 中,`getters` 被局部化了 // 你可以使用 getter 的第四个参数来调用 `rootGetters` someGetter (state, getters, rootState, rootGetters) { getters.someOtherGetter // -> 'foo/someOtherGetter' rootGetters.someOtherGetter // -> 'someOtherGetter' }, someOtherGetter: state => { ... } }, actions: { // 在这个模块中, dispatch 和 commit 也被局部化了 // 他们可以接受 `root` 属性以访问根 dispatch 或 commit someAction ({ dispatch, commit, getters, rootGetters }) { getters.someGetter // -> 'foo/someGetter' rootGetters.someGetter // -> 'someGetter' dispatch('someOtherAction') // -> 'foo/someOtherAction' dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction' commit('someMutation') // -> 'foo/someMutation' commit('someMutation', null, { root: true }) // -> 'someMutation' }, someOtherAction (ctx, payload) { ... } } } } ~~~ ## **带命名空间的绑定函数** 当使用了命名空间的模块,要在组件中使用`mapState`,`mapGetters`,`mapActions`和`mapMutations`访问时,写起来会比较繁琐: ~~~ computed: { ...mapState({ a: state => state.some.nested.module.a, b: state => state.some.nested.module.b }) }, methods: { ...mapActions([ 'some/nested/module/foo', // -> this['some/nested/module/foo']() 'some/nested/module/bar' // -> this['some/nested/module/bar']() ]) } ~~~ 针对上述问题Vuex提供了两种方法解决: **1.将模块的空间名称作为第一个参数传递给`mapState`,`mapGetters`,`mapActions`和`mapMutations`** **2.使用`createNamespacedHelpers`函数创建带命名空间的`mapState`,`mapGetters`,`mapActions`和`mapMutations`** >[info] 将命名空间作为参数传递: ~~~ computed: { ...mapState('some/nested/module', { a: state => state.a, b: state => state.b }) }, methods: { ...mapActions('some/nested/module', [ 'foo', // -> this.foo() 'bar' // -> this.bar() ]) } ~~~ >[info] 使用`createNamespacedHelpers`函数: ~~~ import { createNamespacedHelpers } from 'vuex' const { mapState, mapActions } = createNamespacedHelpers('some/nested/module') export default { computed: { // 在 `some/nested/module` 中查找 ...mapState({ a: state => state.a, b: state => state.b }) }, methods: { // 在 `some/nested/module` 中查找 ...mapActions([ 'foo', 'bar' ]) } } ~~~