我们知道,vuex是vue技术栈中很重要的一部分,是一个很好用的状态管理库。
如果你的项目没有那么复杂,或者对vuex的使用没有那么重度,那么,是用不着modules功能的。
但如果你写着写着就发现你的vuex 代码过于臃肿,那么就可能需要modules功能来进行模块化改造了。
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
——vuex文档
那么,怎么改呢?
以文档的计数器demo为例:
这是demo的vuex代码:
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) // root state object. // each Vuex instance is just a single state tree. const state = { count: 0 } // mutations are operations that actually mutates the state. // each mutation handler gets the entire state tree as the // first argument, followed by additional payload arguments. // mutations must be synchronous and can be recorded by plugins // for debugging purposes. const mutations = { increment (state) { state.count++ }, decrement (state) { state.count-- } } // actions are functions that cause side effects and can involve // asynchronous operations. const actions = { increment: ({ commit }) => commit('increment'), decrement: ({ commit }) => commit('decrement'), incrementIfOdd ({ commit, state }) { if ((state.count + 1) % 2 === 0) { commit('increment') } }, incrementAsync ({ commit }) { return new Promise((resolve, reject) => { setTimeout(() => { commit('increment') resolve() }, 1000) }) } } // getters are functions const getters = { evenOrOdd: state => state.count % 2 === 0 ? 'even' : 'odd', originNumber: state => state.count } // A Vuex instance is created by combining the state, mutations, actions, // and getters. export default new Vuex.Store({ state, getters, actions, mutations })
1 新建文件,叫part_a.js
2 store.js的代码复制进去,并修改:
// import Vue from 'vue' // import Vuex from 'vuex' // Vue.use(Vuex) // root state object. // each Vuex instance is just a single state tree. const state = { count: 0 } // mutations are operations that actually mutates the state. // each mutation handler gets the entire state tree as the // first argument, followed by additional payload arguments. // mutations must be synchronous and can be recorded by plugins // for debugging purposes. const mutations = { increment (state) { state.count++ }, decrement (state) { state.count-- } } // actions are functions that cause side effects and can involve // asynchronous operations. const actions = { increment: ({ commit }) => commit('increment'), decrement: ({ commit }) => commit('decrement'), incrementIfOdd ({ commit, state }) { if ((state.count + 1) % 2 === 0) { commit('increment') } }, incrementAsync ({ commit }) { return new Promise((resolve, reject) => { setTimeout(() => { commit('increment') resolve() }, 1000) }) } } // getters are functions const getters = { evenOrOdd: state => state.count % 2 === 0 ? 'even' : 'odd', originNumber: state => state.count } // A Vuex instance is created by combining the state, mutations, actions, // and getters. export default { namespaced: true, state, getters, actions, mutations }
注意白底的部分:import 和 use 被注释了,输出变成了 export default { },输出对象中加上了 namespaced: true
3 修改store.js
import Vue from 'vue' import Vuex from 'vuex' import part_a from './part_a' Vue.use(Vuex) export default new Vuex.Store({ modules: { part_a } })
因为业务逻辑代码放进了part_a.js,所以store.js就不需要保留这一部分。
注意白底的部分:加上了part_a.js的引用,Store()中的对象只有modules对象,里面是引用的part_a。
4 修改*.vue文件
...
computed: { ...mapGetters([ 'evenOrOdd', 'originNumber' ]), }, methods: { ...mapActions([ 'increment', 'decrement', 'incrementIfOdd', 'incrementAsync' ]) },
...
...
computed: { ...mapGetters('part_a', [ 'evenOrOdd', 'originNumber' ]), }, methods: { ...mapActions('part_a', [ 'increment', 'decrement', 'incrementIfOdd', 'incrementAsync' ]) },
...
注意白底的部分。加一个参数就可以了。
mutations 和 state 可以只有私有调用,所以mapMutations和mapState
就不需要了。
以上。