深入vuex原理(上)

孔維國發表於2019-02-28

前言

vuex作為vue生態的重要組成部分,是對store進行管理的一柄利劍。簡而言之,vuex是vue的狀態管理器。使用vuex可用使資料流變得清晰、可追蹤、可預測,更可以簡單的實現 類似時光穿梭 等高階功能,對於複雜的大型應用來講,vuex將變得尤為重要,對於 store的切分、store的module化、store的變更、store的追蹤 等等 store的管理工作,使用vuex 管理store會大大提高專案的穩定性,擴充套件性!本篇將通過vuex的原始碼對vuex 的設計以及實現原理 進行剖析!


注:本篇文章只展示關鍵核心程式碼,一來由於篇幅原因,二來展示核心程式碼更容易讓人理解!再者,本篇屬於 vuex 高階篇,對於本篇章中 涉及的 vue 相關的機制 以及 vuex的 高階使用 等 不進行過多贅述!請自行前往官網檢視!


準備

淺析vuex的構成

vuex 引入 StateGetter 的概念對狀態進行定義;使用 MutationAction對狀態進行變更;引入Module對狀態進行模組化分割;引入外掛對狀態進行快照、記錄、以及追蹤等;提供了mapState、mapGetters、 mapActions、 mapMutations 輔助函式方便開發者在vm中處理store。具體構成關係如下:

vuex部件構成關係圖

淺析vuex的使用

vuex的使用方式很簡單,具體使用細節請參見 vuex官網,本文為了剖析原始碼方便,只進行簡單介紹!我們只需要利用vue的use機制將 例項化後的store物件 注入vue例項即可!如下圖:

vuex裝載過程圖解

核心程式碼如下:


Vue.use(Vuex); // 1. vue的外掛機制,安裝vuex
let store = new Vuex.Store({ // 2.例項化store,呼叫install方法
 	state,
 	getters,
 	modules,
 	mutations,
 	actions,
 	plugins
});
new Vue({ // 3.注入store, 掛載vue例項
	store,
	render: h=>h(app)
}).$mount('#app');

複製程式碼

對vuex的疑問

我們在使用vuex對store進行管理的同時,不禁會問:

  • vuex的store是如何注入到元件中的?
  • vuex的state 和 getter 是如何對映到 各個元件例項中自動更新的?

本篇章旨在解決以上疑問,讓我們一起深入vuex的原理,揭開vuex的神祕面紗吧!

探祕原理

本部分將針對以上疑問,通過原始碼分析,剖析核心程式碼,對問題進行解答。

疑問:vuex的store是如何注入到元件中的?

要解答這個問題,我們先從vuex的使用表象上著手,從上面的介紹我們知道,使用vuex之前我們要對vuex進行安裝!核心程式碼如下:

Vue.use(Vuex); // vue的外掛機制,安裝vuex外掛
複製程式碼

原始碼分析
上面的程式碼得益於vue的外掛機制,會在呼叫vuex的 install方法時,裝載vuex! 所以我們直接關注 install方法的實現,其核心程式碼如下:

Vue.mixin({ beforeCreate: vuexInit });
複製程式碼

可見,store注入 vue的例項元件的方式,是通過vue的 mixin機制,藉助vue元件的生命週期 鉤子 beforeCreate 完成的。即 每個vue元件例項化過程中,會在 beforeCreate 鉤子前呼叫 vuexInit 方法。下面,我們將焦點聚焦在 vuexInit 函式。 下面為 vuexInit 的核心程式碼!

this.$store = typeof options.store === 'function'
    ? options.store()
    : options.store
複製程式碼

該程式碼的核心問題是this的指向,得益於mixin機制,this將指向 vue元件例項!最終,我們可以再 vue元件例項上獲得vuex 的store 物件的引用 $store!圖示如下:

vuex裝載原理圖示
分析至此,我們已經得出該問題的答案!

結論

vuex利用了vue的mixin機制,混合 beforeCreate 鉤子 將store注入至vue元件例項上,並註冊了 vuex store的引用屬性 $store!

對於其餘問題的解答,請前往 深入vuex原理(下)

相關文章