對於vue這類mvvm框架來講,其核心就是組件與數據,所以作好相應的數據管理極爲重要。這裏分享下vuex數據模塊化管理的方法,有利於搭建便於維護、協做的vue項目。css
模塊化的概念已經在js、css中大量的用到,已再也不陌生,其可增長代碼的複用、擴展性、維護性等,對於一個大型的系統來講,必不可少。這裏也但願提供一種有效的模塊化數據管理方式,讓協做變的更爲高效。vue
state: {}, // 存儲數據的狀態 getters: {}, // 獲取vuex數據(state)的統一接口 mutations: {}, // 存vuex數據(state)的統一接口 actions: {}, // vuex內的異步操做接口
項目有兩個模塊,一個home頁面,一個poetry頁面,對應不一樣的vuex數據模塊,其vuex的管理方式以下:vuex
// home.js export default new Vuex.Store({ state: {...}, mutations: {...} }) // poetry.js export default new Vuex.Store({ state: {...}, getters: {...} }) // vuex調用 if (pathname.indexOf('/home') >= 0) { store = require('/vuex/home').default } else if (pathname.indexOf('/poetry') >= 0) { store = require('/vuex/home').default }
因爲每一個單頁對應會生成一個全新的vuex,這樣就會形成vuex數據的丟失(單頁跳轉、回退時),這就是沒有實現vuex的模塊化管理及數據共享共享。那麼怎麼樣進行模塊化管理呢?框架
簡單的vuex管理代碼以下:異步
// home.js ... export default { state, getters, actions, mutations } // poetry.js ... 同home.js~~ // index.js ... import common from './common' import home from './home' import poetry from './poetry' Vue.use(Vuex) export default new Vuex.Store({ state: {}, getters: {}, mutations: {}, actions: {}, modules: { common, home, poetry } }) // 調用方法以下 import store from 'src/store/index'
如此,vuex模塊化後的結構以下:mvvm
圖一 vuex模塊化的結構模塊化
一個獨立項目,僅有一處進行new Vuex操做,防止vuex丟失。但上圖的方法,能夠實現簡單項目的管理,在多人協做下仍然存在數據操做隱患。首先來看下重名狀態下,各個屬性的表現。ui
重名的狀況下,state會自動根據模塊確認命名空間(獨立的屬性調用)。再看getters、mutations、actions,其與state不一樣,會引起重名問題,具體表現以下:this
gettersspa
在重名的狀況下,僅首先註冊的getters會生效,同時報錯,提示重名。
錯誤以下:
圖二 getters重名報錯圖
mutations/action
在重名狀況下,多個重名方法都將被調用。(以mutations爲例)
this.updateInitInfo('poetry string’) // home.js const mutations = { updateInitInfo(state, string) { state.initInfo = string console.log('home update', string) } } // poetry.js const mutations = { updateInitInfo(state, string) { state.pageName = string console.log('poetry update', string) } }
在poetry中調用,執行結果以下:
圖3 mutations的重命名執行結果
由圖3,能夠得出結論,方法會按序執行,且無報錯和警告。
對於這類方法的重名調用,比較難察覺,多人協做時,較容易出現數據共享錯誤,因此須要用另外的方法來增強配置,使得強調 單一調用 的協做場景,也能夠高效的展開。
vuex自帶模塊化方法,爲namespaced:true。經過對模塊進行命名空間設置,就能分模塊進行管理。
目錄結構
圖4 vuex的目錄結構
其中address模塊的增長,是爲了適應更爲複雜的應用需求。相關設置代碼以下:
// address/index.js import addr1 from './addr1' import addr2 from './addr2' import addrList from './addrList' export default { namespaced: true, modules: { addr1, addr2, addrList } } // home.js const state = { initInfo: 'hello hity' } const getters = { initInfo(state, getters) { return state.initInfo } } const actions = { getInfo({commit, state}) { commit('updateInitInfo', 'getInfo') } } const mutations = { updateInitInfo(state, string) { state.initInfo = string console.log('home update', string) } } export default { namespaced: true, state, getters, actions, mutations } // index.js ...... export default new Vuex.Store({ state: {}, getters: {}, mutations: {}, actions: {}, modules: { common, home, poetry, address } })
運行結果vuex視圖以下:
圖5 vuex運行後的結構圖
由上圖可見,經過命名空間設置的getters、mutaions、actions均可以生成本身獨有的方法名,從而實現模塊化。這樣的方法名,如何調用呢?調用方法有以下幾種[以貼出代碼的home模塊爲例]:
// xxx.vue中調用 a、經過store直接調用: state:this.$store.state.home.initInfo getters: this.$store.getters['home/initInfo'] mutations: this.$store.commit('home/updateInitInfo', 'set home init info') actions: this.$store.dispatch('home/getInfo') b、配合vuex的createNamespacedHelpers方法使用 import { createNamespacedHelpers } from 'vuex' const { mapActions, mapState, mapMutations, mapGetters } = createNamespacedHelpers('home') computed: { ...mapState({ initInfoState: state => state.initInfo }), ...mapGetters([ 'initInfo' ]) }, methods: { ...mapMutations([ 'updateInitInfo' ]), ...mapActions([ 'getInfo' ]) } c、使用原始的mapX方法 import { mapActions, mapState, mapMutations, mapGetters } from 'vuex' computed: { ...mapState({ initInfoState: state => state.home.initInfo }), ...mapGetters('home', [ 'initInfo' ]) } methods: { ...mapMutations('home', [ 'updateInitInfo' ]), ...mapActions('home', [ 'getInfo' ]) }
從vuex運行後的結構圖能夠看出,state的模塊名成爲其屬性名,從而實現模塊化;而getters、mutations、actions的模塊名,則成爲方法名的前綴,經過'/'分隔,從而實現模塊化。從調用方法上能夠看出,更容易看出二者的區別。若是你的代碼是從非模塊化,到模塊化的改造,且都是使用的mapX方法進行方法管理,那麼使用方案b的state方法,結合方案c的mapGetters、mapMutations、mapActions,將使得改形成本最小化。
tips:使用vuex的項目,建議使用mapX方法進行統一的管理,對vuex的調用較爲直觀,也便於未來的擴展和改造。