前置篇不會那可不行!Vuex原始碼學習(六)action和mutation如何被呼叫的(前置準備篇) 在前置準備篇我們已經知道被處理好的action與mutation都被集中放置在哪裡了。下面就要看dispacth和commit如何去呼叫它們。
dispatch與commit的實現
commit:

// 接收一個物件
this.$store.commit({type : 'setName',name : 'xLemon'});
this.$store.commit('setName',{name : 'xLemon'});
這兩個基本等價。
只是第一種方式mutation接收的payload會比第二種多一個type屬性,
整理的部分並不關鍵
複製程式碼
type是我們要找的mutation的名字,如何找到mutation呢?
通過 this._mutations[type] 找到要執行的mutation
複製程式碼
所以type一定要是mutation的全名
所以我們通過commit找mutation的時候有名稱空間的時候就要輸入全名,(那種帶很多/的)。沒有這個名字的mutation容錯處理,然後在withCommit函式的包裹下,完成了mutation的執行(所有mutation啊,全名相同的mutation都會被執行)。然後呢遍歷_subscribers裡面的函式進行執行。
_subscribers這是什麼?在一開始我們可以註冊一些內容(函式),在commit完成時被通知執行。(觀察者模式)如何註冊在這一章就不多講了!後面章節會統一講述。
這就是commit做的事情。
dispatch呢?

固定disptach與commit的this指向
//在vue元件內一個方法如果多次使用dispatch和commit,就會很麻煩。
this.$store.dispatch('xxx',payload);
this.$store.commit('xxx',payload);
const {dispatch,commit} = this.$store;
//這相當於建立變數,然後把this.$store的dispatch與commit賦值給它們。
//有經驗的都應該知道,函式dispatch和commit的this指向在嚴格模式下指向undefined。
// 非嚴格模式下指向window,
// 剛才的原始碼中我們也看到了,dispatch和commit都依賴於Store例項。怎麼辦??
複製程式碼
解決方法如下:

action與mutation函式的引數都有哪些?怎麼來的?
看一個簡單的mutation:
export const setName = function(state,payload) {
state.name = payload;
};
複製程式碼
這個時候不經意間有了一個疑惑?state哪裡來的。 這就要從mutation被註冊的函式內找原因了

我們發現,entry是被一個函式包裹起來,然後將local.store和payload繫結到這個handle的引數上,然後把handle的this指向鎖定到了Store例項上,所以mutation在被commit呼叫的時候只傳入了一個引數payload, 但是mutation函式執行的時候就有了兩個引數。
下面看一下action:

{
dispatch : local.dispatch,
commit:local.commit,
getter: local.getters,
state: local.state,
rootGetters:store.getters,
rootState:store.state
}
複製程式碼
分為兩種一種是local的、一種是store的。mutation中好像也有使用local,那麼local的意義是什麼呢?我們下一節會講述local的含義以及makeLocalContext、makeLocalGetters兩個函式的作用。 還是要給個小線索,在模組樹的層級很高的時候,我們在使用state的時候要一層一層找尋嗎?
總結
- dispatch與commit在執行的時候,都是根據傳入的全名action、mutation去Store例項的_actions、_mutations中找到對應的方法,進行執行的。
- dispatch和commit中都使用了this(指向Store例項),為了防止this的指向改變從而出現問題,就把原型上的dispatch與commit在constructor中處理到了例項本身,這個過程做了this指向的繫結(call)。
- action和mutation在執行的時候,引數都是在註冊的時候就繫結了一部分,所以action與mutation在使用的時候可以訪問到state等很多內容。
下一章;離開action與mutation 來討論一下local的含義以及makeLocalContext、makeLocalGetters兩個函式的作用
我是一個應屆生,最近和朋友們維護了一個公眾號,內容是我們在從應屆生過渡到開發這一路所踩過的坑,已經我們一步步學習的記錄,如果感興趣的朋友可以關注一下,一同加油~
