前置篇不會那可不行!Vuex源碼學習(六)action和mutation如何被調用的(前置準備篇)
在前置準備篇咱們已經知道被處理好的action與mutation都被集中放置在哪裏了。下面就要看dispacth和commit如何去調用它們。vue
commit:segmentfault
首先呢咱們要校訂參數,把傳入的參數整理下
主要是處理這種形式promise
// 接收一個對象 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完成時被通知執行。(觀察者模式)如何註冊在這一章就很少講了!後面章節會統一講述。this
這就是commit作的事情。spa
dispatch呢?code
與commit大同小異,
也有一個_actionSubscribers的屬性,在dispatch執行以前所有調用。
對於dispatch Vuex推薦的是放置異步任務,在註冊action的時候已經被強制promise化了,因此有多個同名action會經過Promise.all來處理。在action的先後都有對應的鉤子函數執行。對象
//在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實例。怎麼辦??
解決方法以下:
dispatch和commit是Store原型鏈上的方法,在constructor內註冊了構造函數內的方法,把原型上的dispatch和commit進行了一個this指向的強制綁定,經過call讓兩個方法永遠指向Store的實例上,保證了dispatch和commit不會由於賦值給其他變量等操做致使this指向改變從而發生問題
看一個簡單的mutation:
export const setName = function(state,payload) { state.name = payload; };
這個時候不經意間有了一個疑惑?state哪裏來的。
這就要從mutation被註冊的函數內找緣由了
handle是咱們要被註冊的一個mutation,entry是這個同名mutation的容器(存儲全部的這個名字的mutation,通常只有一個)在吧handle放入entry的過程當中,
咱們發現,entry是被一個函數包裹起來,而後將local.store和payload綁定到這個handle的參數上,而後把handle的this指向鎖定到了Store實例上,因此mutation在被commit調用的時候只傳入了一個參數payload,
可是mutation函數執行的時候就有了兩個參數。
下面看一下action:
按照剛纔的分析action在被dispatch調用的時候會接收一個參數,可是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的時候要一層一層找尋嗎?
下一章;離開action與mutation 來討論一下local的含義以及makeLocalContext、makeLocalGetters兩個函數的做用