Vuex模塊化管理

vuex的基本用法> 直接上代碼,一眼飄過 jsimport Vue from 'vue';import Vuex from 'vuex'; Vue.use(Vuex); let state = { count: 6,} let getters = { countResult(state){ return '統計結果爲' + state.count; }} let actions = { incrementYB({commit,state}){ // 異步,比如發請求後再commit setTimeout(() => { commit('incrementTB'); }, 1000) }} let mutations = { incrementTB(state){ state.count++; }} export default function createVuexStore(){ return new Vuex.Store({ state, actions, mutations, getters, });}> 當然,我們真正項目中不會這樣寫,肯定拆成一個個文件模塊,然後引入來使用,另外,我們還會將變量抽成一個文件types.js(下文會講),方便統一管理。 # vuex的模塊化管理> 如果我們按照上述寫法來管理狀態,那麼代碼將顯得格外臃腫。 所以,我們可以根據下圖的思路進行模塊管理。>根據上面的圖片,將每個模塊的state、action和mutation根據模塊進行劃分,其實,getters也可以根據模塊來劃分,但是考慮到getters類似於計算屬性computed,可能會去計算多個模塊之間的狀態,所以也可以將getters不做模塊化,統一管理。 ## vuex模塊化目錄結構jsvuexStore | ---------modules | | | --------user.js | ---------getters.js | ---------types.js | ---------index.js## 模塊化狀態文件>根據第一張圖,我們將state、action和mutation進行模塊劃分,那麼對於用戶模塊的state、action和mutation如何劃分呢?內容vuexStore/modules/user.js如下:jsimport { ADD_USER, GET_AVG_AGE } from '../types.js';const user = { namespaced: true, state: { count: 5, userList: [ {id:0, name: 'yuhua0', age: 10}, {id:1, name: 'yuhua1', age: 11}, {id:2, name: 'yuhua2', age: 12}, {id:3, name: 'yuhua3', age: 13}, {id:4, name: 'yuhua4', age: 14}, ] }, mutations: { [GET_AVG_AGE](state){ return state.userList.reduce((pre, next) => { return pre + next.age }, 0)/state.userList.length; }, [ADD_USER](state, playload){ state.userList.push(playload); state.count++; } }, actions: { addUserAsync({commit}, playload){ setTimeout(() => { commit(ADD_USER, playload); }, 1000) } }} export default user;- state、actions和mutations的用法,幾乎跟非模塊化一樣,只不過是放在了user對象中。- namespaced這個字段爲true,表示開啓命名空間,這代表着你要使用該文件內的數據時,數據都在該命名空間下,那這個命名空間是什麼呢?index.js中的modules下的key就是命名空間(下文會講)。這其實是vuex模塊化的關鍵一步。- 另外,我們在該文件開頭導入了types.js文件,以及將變量使用在了mutations和actions中,這個types.js其實是爲了統一管理提交數據的動作。types.js不需要做模塊化,這樣能讓開發者一看就知道存在哪些提交數據的操作。 ## types.js 提交類型管理> 我們知道,改變store中數據狀態的唯一方法就是提交commit,所以,我們可以所有的commit動作用一個文件types.js統一管理,這樣讓我們看起來一目瞭然。同時,如果需要改變提交動作的名稱,也只要在這個文件內統一修改就可以了。jsexport const ADD_USER = 'ADD_USER';export const GET_AVG_AGE = 'GET_AVG_AGE';## getters.js 統一管理> 上面已經說明,getters是可以放入module中模塊化管理的,但也可以統一管理,原因是我們對數據進行計算時,數據可能是來自多個模塊的。 jslet getters = { userList: state => state.users.userList, userCount: state => state.users.count,} export default getters;## 入口文件管理> 有了模塊中的state、mutation、actions和外部的getters,以及types,我們可以將他們一起收口,導入入口文件index.js中:jsimport Vue from 'vue';import Vuex from 'vuex'; Vue.use(Vuex); // 模塊導入import users from './modules/user' // getters導入import getters from './getters.js'; export default function createVuexStore(){ return new Vuex.Store({ modules: { users, }, getters, });}# vuex模塊化的使用## 普通使用方法>上面已經將vuex模塊化結構搭建完畢,下面我們來看看如何使用模塊化的vuex - 獲取state數據:store.state.模塊化命名空間.count - 獲取getter數據: store.getters.userList - 注意:如果你的getter是模塊化的,那你獲取數據也是store.getters.userList,因爲會自動合併在一起 - 提交mutations: store.commit(“模塊化命名空間/mutation方法名”, playload) - 提交actions: store.dispatch(“模塊化命名空間/actions方法名”, playload)- 假設我們有用戶模塊:user.vuevue<template> <div> <h4 style="display:inline-block;">{{$store.state.users.count}}</h4> <ul> <li v-for="user in $store.getters.userList" :key="user.id"> {{user.name}}今年{{user.age}}歲了 </li> </ul> <button @click="addUser">同步提交數據</button> <button @click="addUserAsync">異步提交數據</button> </div></template> <script>import { ADD_USER, GET_AVG_AGE } from '../vuexStore/types.js'export default { methods: { addUser(){ this.$store.commit("users/" + ADD_USER, {name: 'yuhuahuayu', age: 5}) }, addUserAsync(){ this.$store.dispatch("users/addUserAsync", {name: 'yuhuahuayuAsync', age: 6}) } }}</script>## 輔助函數使用方法> 感謝vuex爲我們提供了非常漸變的輔助函數使用方法,能夠更快捷的達到上面的效果- mapGetters: 寫在computed中 js computed: { ...mapGetters(['userCount']), }- 注意:getters不需要傳參,mapGetters的參數寫成數組- mapState: 寫在computed中 js computed: { ...mapState({ userList: state => state.users.userList, count: state => state.users.count, }) }- 參數攜程對象的形式- mapMutations: 寫在methods中,有兩種寫法: - 沒有payload載荷: js methods: { ...mapMutations(['提交動作0', '提交動作1']), }> 因爲寫在methods中,所以按照method的調用方法調用,比如: html <button @click="提交動作0">確定</button>- 有payload載荷: js methods: { ...mapMutations({ addUser: `users/${ADD_USER}`, }) }> 這樣的話,我們如果要派發users/${ADD_USER}動作,就只需要調用addUser即可,有payload載荷的話,在調用addUser方法時傳入,比如: html <button @click="addUser({name: 'yuhua', age: 6})">確定</button>- mapActions: 寫在methods中,也是兩種方法,與mapMutations一樣,在此不做贅述。如果不明白,可以看下面的示例: vue<template> <div> {{'來自Getters的Count' + userCount}} <h4 style="display:inline-block;">{{count}}</h4> <ul> <li v-for="user in userList" :key="user.id"> {{user.name}}今年{{user.age}}歲了 </li> </ul> <button @click="addUser({name: 'yuhuahuayu', age: 5})">同步提交數據</button> <button @click="addUserAsync({name: 'yuhuahuayuAsync', age: 6})">異步提交數據</button> </div></template> <script>import { ADD_USER, GET_AVG_AGE } from '../vuexStore/types.js'import { mapGetters, mapState, mapMutations, mapActions } from 'vuex';export default { methods: { ...mapMutations({ addUser: `users/${ADD_USER}`, }), ...mapActions({ addUserAsync: `users/addUserAsync`, }) }, computed: { ...mapState({ userList: state => state.users.userList, count: state => state.users.count, }), ...mapGetters(['userCount']) }}</script># 老項目vuex的模塊化改造> 一個項目的開發並不難,難的是對古老的項目的改造,當然,在改造過程中,往往不是難,更多的是煩… > 那麼,對於老項目的vuex如何儘可能少改動原有代碼下去改造成模塊化的vuex? ## 保持老數據不變> 老數據一般是下面這樣的,或者對下面的數據做了文件拆分,然後導入進來jsimport Vue from 'vue';import Vuex from 'vuex'; Vue.use(Vuex); let state = { count: 6,} let getters = { countResult(state){ return '統計結果爲' + state.count; }} let actions = { incrementYB({commit,state}){ // 異步,比如發請求後再commit setTimeout(() => { commit('incrementTB'); }, 1000) }} let mutations = { incrementTB(state){ state.count++; }} export default function createVuexStore(){ return new Vuex.Store({ state, actions, mutations, getters, });}- OK,咱們對這部分保持不變,那麼當新的模塊開發的時候,先將當前老數據的getters,移到getters.js文件中(原本就有的就不用變了)。- 然後,創建modules,比如開發users模塊,如下:js... // 模塊導入import users from './modules/user' // getters導入import getters from './getters.js'; export default function createVuexStore(){ return new Vuex.Store({ modules: { users, }, getters, state, actions, mutations, });}- 接着在創建modules/user.js,內容與上文的modules/user.js一致(當前文件結構目錄:vuex的模塊化管理>模塊化狀態文件)。- 然後創建types.js,將新模塊的commit的動作,都抽離到types.js中 # 老項目vuex的模塊化改造後的使用- 對於vuex中的老數據,使用就按照正常的使用方法,即: - state: store.state.count - getter: store.getters.getUserList - mutation: store.commit(‘addUser’, {name: ‘yuhua’, age: 18}) - action: store.dispatch(‘addUserAsync’, {name: ‘yuhua’, age: 18})- 對於vuex的心數據,就按照上述所講的模塊化使用方法來使用。> 其實,這種寫法,就是對新老數據管理的兼容。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章