vue之mapMutations的使用
我們通過Mutation來改變store中的state,方法往往是在子組件中使用 this.$store.commit(); 來實現,但是這樣的缺點是不容易查看,並且每次在調用Mutations時都需要添加 $store, 為了方便我們的開發,所以可以使用 mapMutations ,正如對於state, 我們可以使用 mapState 是一樣的 。
首先,在mutation-type.js 中的內容大致如下:
export const INCREMENT_NUMBER = "INCREMENT_NUMBER" export const DECREMENT_NUMBER = "DECREMENT_NUMBER" export const INCREMENT_PRICE = "INCREMENT_PRICE" export const DECREMENT_PRICE = "DECREMENT_PRICE" export const UPDATE_MALL = "UPDATE_MALL" export const UPDATE_PERSON = "UPDATE_PERSON" export const UPDATE_CONTENT = "UPDATE_CONTENT" export const UPDATE_KINDS = "UPDATE_KINDS"
使用大寫,這樣我們可以更容易進行區分。
接着,我們引入:
import { INCREMENT_NUMBER, DECREMENT_NUMBER, INCREMENT_PRICE, DECREMENT_PRICE, UPDATE_MALL, UPDATE_PERSON, UPDATE_CONTENT, UPDATE_KINDS } from './mutation-types.js'
然后就可以在 store 實例下定義了:
mutations: { [INCREMENT_NUMBER] (state) { state.totalNumber++; }, [DECREMENT_NUMBER] (state) { state.totalNumber--; }, [INCREMENT_PRICE] (state, unitPrice) { state.totalPrice += unitPrice; }, [DECREMENT_PRICE] (state, unitPrice) { state.totalPrice -= unitPrice; },
完成了這些基本工作之后,我們就可以在組件中使用:
import {mapMutations} from "vuex"
然后在 methods 下定義,例如:
...mapMutations([ 'UPDATE_CONTENT', "UPDATE_KINDS" ]),
這樣,我們在使用的時候,用this即可。
that.UPDATE_CONTENT(response.data.data);
這里使用了that是因為,如果使用this指向的不是vue實例,之前我們會 var that = this; 這樣就沒有問題了 。
vue中action的用法
在知乎上,有人問了這么一個問題:
這個問題問的非常好! 額,因為這就是我想問的問題。。。
有以下幾種解決方式:
第一:
最高票答案的方法是把所有和服務器端的交互都寫在 actions 中, 而業務代碼里,就只有對actions的異步操作。
也就是說: axios相關代碼寫在actions中, 在.vue文件中來觸發actions。
總體的設計原則是actions是異步的,用來處理業務邏輯的, 而mutation只是簡單的對state的狀態進行改變。
以上是說第一個問題。
而第二個問題最高票認為: 先處理好返回數據,然后將返回數據觸發 mutations。
你可以把state 理解為前端的共用數據庫, mutations 這些是增刪改,getters 是查,所以mutations 里的邏輯應該是越少越好。
第二:
有人建議新建一個service層(當然是在src中),在其中添加一個api.js(或者getData.js)用於請求數據。 然后將接口導出即可。
我的觀點: 不管是哪種原則,其實都是為了方便我們進行編碼而設計的, 並且我單獨列出來上述答案,是因為我覺得他們有相同之處, 比如我們確實應當將異步的請求寫在actions中,而actions中如果寫了太多的 axios 請求邏輯也會顯得十分繁瑣,所以,我們這時就需要添加一個 service 層,該層中添加 api.js ,用於調用其中的接口。 參考代碼
好處:
- 如果需要改請求,我們直接進入service層進行修改即可。
- 如果需要修改異步調用,直接進入actions中修改即可。
即通過代碼的有效整理后,邏輯性更加清楚, 而不會造成混亂。
vue中mapActions的使用
使用mapActions的方法大致和mapMutations的方法相同,現在簡單介紹如下。
我們知道使用actions的目的就是用來處理異步的操作。
比如: 我們獲取一個用戶信息,使用axios發送http請求,這里使用actions。
第一: 因為actions的本質是提交mutations,所以:
import { UPDATE_PERSON, } from './mutation-types.js'
然后:
mutations: { [UPDATE_PERSON] (state, curPerson) { state.curPerson = curPerson; }, },
這樣,mutations 的相關工作就做好了。
第二:定義actions, 使用action, 方法中一般都是要有異步的請求的,否則就沒有使用action的必要了.
actions: { updatePerson ({commit, state}) { axios.get('/bbg/user/user_base_info', { params: { uid: 22478849 } }).then(function (response) { if (response.data.code == 8) { commit(UPDATE_PERSON, response.data.data); } }); }, }
這里比較重要的就是 commit 了,可以看到在updatePerson中,我們傳遞的參數一般是{commit, state}, 當請求結束之后,我們就可以commit了。
注意
在action中對commit mutations時,一般都只接受兩個參數,第一個參數是 mutations 中的名稱,第二個參數是我們需要向mutations傳遞的值,這個值往往是通過異步的http請求獲得的值和其他相關值,對於傳遞多個參是不支持的,所以我們的做法就是將多個參數封裝到多個參數中,這樣不就可以了嗎!!! 如下所示:
if (response.data.code == 626) { for (let i = 0; i < response.data.data.length; i++) { console.log(response.data.data[i], index); var obj = { index: index, item: response.data.data[i] }; commit(UPDATE_ALL_CONTENT, obj); } index++; resolve(); }
第三: 使用
import {mapActions} from "vuex"
同mapMutations一樣,先從vuex中引入。
在methods下設置:
methods: { ...mapActions([ 'updatePerson' ]),
最后,當用戶點擊按鈕或。。
getPerson: function () { this.updatePerson(); }
即直接使用 this.updatePerson() 來調用。 和 mutations 的調用非常類似,只是actions在中間加了一層異步的方法。
說明: 使用actions時也是可以傳遞參數的,比如這里: this.updatePerson("參數"), 然后updatePerson ({commit, state}, str) 這種形式就可以接收到參數了。
當然可以也是可以傳遞payLoad的,比如 updatePerson({commit, state}, payload) 然后我們在函數中使用payload.foo、payload.bar即可。
參考代碼:
https://github.com/bailicangdu/vue2-elm/tree/master/src
https://github.com/bailicangdu/vue2-elm/blob/master/src/page/confirmOrder/confirmOrder.vue
參考文章:
https://www.zhihu.com/question/57133837