Vuex 框架原理與源碼分析(分享一)

? ? ? ? Vuex是一個專為Vue服務(wù)情龄,用于管理頁面數(shù)據(jù)狀態(tài)、提供統(tǒng)一數(shù)據(jù)操作的生態(tài)系統(tǒng)。它集中于MVC模式中的Model層弟灼,規(guī)定所有的數(shù)據(jù)操作必須通過 action – mutation – state change 的流程來進行爬凑,再結(jié)合Vue的數(shù)據(jù)視圖雙向綁定特性來實現(xiàn)頁面的展示更新困乒。統(tǒng)一的頁面狀態(tài)管理以及操作處理,可以讓復(fù)雜的組件交互變得簡單清晰贰谣,同時可在調(diào)試模式下進行時光機般的倒退前進操作娜搂,查看數(shù)據(jù)改變過程,使code debug更加方便吱抚。

最近在開發(fā)的項目中用到了Vuex來管理整體頁面狀態(tài)百宇,遇到了很多問題。決定研究下源碼秘豹,在答疑解惑之外携御,能深入學(xué)習(xí)其實現(xiàn)原理。

先將問題拋出來既绕,使學(xué)習(xí)和研究更有針對性:

使用Vuex只需執(zhí)行 Vue.use(Vuex)啄刹,并在Vue的配置中傳入一個store對象的示例,store是如何實現(xiàn)注入的凄贩?

state內(nèi)部是如何實現(xiàn)支持模塊配置和模塊嵌套的誓军?

在執(zhí)行dispatch觸發(fā)action(commit同理)的時候,只需傳入(type, payload)疲扎,action執(zhí)行函數(shù)中第一個參數(shù)store從哪里獲取的昵时?

如何區(qū)分state是外部直接修改,還是通過mutation方法修改的椒丧?

調(diào)試時的“時空穿梭”功能是如何實現(xiàn)的壹甥?

注:本文對有Vuex有實際使用經(jīng)驗的同學(xué)幫助更大,能更清晰理解Vuex的工作流程和原理壶熏,使用起來更得心應(yīng)手句柠。初次接觸的同學(xué),可以先參考Vuex官方文檔進行基礎(chǔ)概念的學(xué)習(xí)。

一溯职、框架核心流程

進行源碼分析之前管怠,先了解一下官方文檔中提供的核心思想圖,它也代表著整個Vuex框架的運行流程缸榄。

Vuex框架

如圖示渤弛,Vuex為Vue Components建立起了一個完整的生態(tài)圈,包括開發(fā)中的API調(diào)用一環(huán)甚带。圍繞這個生態(tài)圈她肯,簡要介紹一下各模塊在核心流程中的主要功能:

1、Vue Components:Vue組件鹰贵。HTML頁面上晴氨,負責(zé)接收用戶操作等交互行為,執(zhí)行dispatch方法觸發(fā)對應(yīng)action進行回應(yīng)碉输。

2籽前、dispatch:操作行為觸發(fā)方法,是唯一能執(zhí)行action的方法敷钾。

3枝哄、actions:操作行為處理模塊。負責(zé)處理Vue Components接收到的所有交互行為阻荒。包含同步/異步操作挠锥,支持多個同名方法,按照注冊的順序依次觸發(fā)侨赡。向后臺API請求的操作就在這個模塊中進行蓖租,包括觸發(fā)其他action以及提交mutation的操作。該模塊提供了Promise的封裝羊壹,以支持action的鏈式觸發(fā)蓖宦。

4、commit:狀態(tài)改變提交操作方法油猫。對mutation進行提交稠茂,是唯一能執(zhí)行mutation的方法。

5眨攘、mutations:狀態(tài)改變操作方法主慰。是Vuex修改state的唯一推薦方法嚣州,其他修改方式在嚴格模式下將會報錯鲫售。該方法只能進行同步操作,且方法名只能全局唯一该肴。操作之中會有一些hook暴露出來情竹,以進行state的監(jiān)控等。

6匀哄、state:頁面狀態(tài)管理容器對象秦效。集中存儲Vue components中data對象的零散數(shù)據(jù)雏蛮,全局唯一,以進行統(tǒng)一的狀態(tài)管理阱州。頁面顯示所需的數(shù)據(jù)從該對象中進行讀取挑秉,利用Vue的細粒度數(shù)據(jù)響應(yīng)機制來進行高效的狀態(tài)更新。

7苔货、getters:state對象讀取方法犀概。圖中沒有單獨列出該模塊,應(yīng)該被包含在了render中夜惭,Vue Components通過該方法讀取全局state對象姻灶。

Vue組件接收交互行為,調(diào)用dispatch方法觸發(fā)action相關(guān)處理诈茧,若頁面狀態(tài)需要改變产喉,則調(diào)用commit方法提交mutation修改state,通過getters獲取到state新值敢会,重新渲染Vue Components曾沈,界面隨之更新。

二鸥昏、目錄結(jié)構(gòu)介紹

打開Vuex項目晦譬,看下源碼目錄結(jié)構(gòu)。

源碼目錄結(jié)構(gòu)

Vuex提供了非常強大的狀態(tài)管理功能互广,源碼代碼量卻不多敛腌,目錄結(jié)構(gòu)劃分也很清晰。先大體介紹下各個目錄文件的功能:

Ⅰ惫皱、module:提供module對象與module對象樹的創(chuàng)建功能像樊;

Ⅱ、plugins:提供開發(fā)輔助插件旅敷,如“時光穿梭”功能生棍,state修改的日志記錄功能等;

Ⅲ媳谁、helpers.js:提供action涂滴、mutations以及getters的查找API;

Ⅳ晴音、index.js:是源碼主入口文件柔纵,提供store的各module構(gòu)建安裝;

Ⅴ锤躁、mixin.js:提供了store在Vue實例上的裝載注入搁料;

Ⅵ、util.js:提供了工具方法如find、deepCopy郭计、forEachValue以及assert等方法霸琴。

三、初始化裝載與注入

先看個簡單的例子:

store.js文件中昭伸,加載Vuex框架梧乘,創(chuàng)建并導(dǎo)出一個空配置的store對象實例。

然后在index.js中庐杨,正常初始化一個頁面根級別的Vue組件宋下,傳入這個自定義的store對象。

問題1所述辑莫,以上實例除了Vue的初始化代碼学歧,只是多了一個store對象的傳入。一起看下源碼中的實現(xiàn)方式各吨。

3.2 裝載分析

index.js文件代碼執(zhí)行開頭枝笨,定義局部 Vue 變量,用于判斷是否已經(jīng)裝載和減少全局作用域查找揭蜒。

然后判斷若處于瀏覽器環(huán)境下且加載過Vue横浑,則執(zhí)行install方法。

install方法將Vuex裝載到Vue對象上屉更,Vue.use(Vuex) 也是通過它執(zhí)行徙融,先看下Vue.use方法實現(xiàn):

若是首次加載,將局部Vue變量賦值為全局的Vue對象瑰谜,并執(zhí)行applyMixin方法欺冀,install實現(xiàn)如下:

來看下applyMixin方法內(nèi)部代碼。如果是2.x.x以上版本萨脑,可以使用 hook 的形式進行注入隐轩,或使用封裝并替換Vue對象原型的_init方法,實現(xiàn)注入渤早。

具體實現(xiàn):將初始化Vue根組件時傳入的store設(shè)置到this對象的$store屬性上职车,子組件從其父組件引用$store屬性,層層嵌套進行設(shè)置鹊杖。在任意組件中執(zhí)行 this.$store 都能找到裝載的那個store對象悴灵,vuexInit方法實現(xiàn)如下:

看個圖例理解下store的傳遞。

頁面Vue結(jié)構(gòu)圖:

對應(yīng)store流向:

四骂蓖、store對象構(gòu)造

上面對Vuex框架的裝載以及注入自定義store對象進行分析积瞒,解決了問題1。接下來詳細分析store對象的內(nèi)部功能和具體實現(xiàn)涯竟,來解答為什么actions赡鲜、getters空厌、mutations中能從arguments[0]中拿到store的相關(guān)數(shù)據(jù)?等問題庐船。

store對象實現(xiàn)邏輯比較復(fù)雜银酬,先看下構(gòu)造方法的整體邏輯流程來幫助后面的理解:

原文出處:美團點評技術(shù)團隊

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市筐钟,隨后出現(xiàn)的幾起案子揩瞪,更是在濱河造成了極大的恐慌,老刑警劉巖篓冲,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件李破,死亡現(xiàn)場離奇詭異,居然都是意外死亡壹将,警方通過查閱死者的電腦和手機嗤攻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來诽俯,“玉大人妇菱,你說我怎么就攤上這事”┣” “怎么了闯团?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長仙粱。 經(jīng)常有香客問我房交,道長,這世上最難降的妖魔是什么伐割? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任候味,我火速辦了婚禮,結(jié)果婚禮上隔心,老公的妹妹穿的比我還像新娘负溪。我一直安慰自己,他們只是感情好济炎,可當我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布川抡。 她就那樣靜靜地躺著,像睡著了一般须尚。 火紅的嫁衣襯著肌膚如雪崖堤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天耐床,我揣著相機與錄音密幔,去河邊找鬼。 笑死撩轰,一個胖子當著我的面吹牛胯甩,可吹牛的內(nèi)容都是我干的昧廷。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼偎箫,長吁一口氣:“原來是場噩夢啊……” “哼木柬!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起淹办,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤眉枕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后怜森,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體速挑,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年副硅,在試婚紗的時候發(fā)現(xiàn)自己被綠了姥宝。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡恐疲,死狀恐怖腊满,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情流纹,我是刑警寧澤糜烹,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站漱凝,受9級特大地震影響疮蹦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜茸炒,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一愕乎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧壁公,春花似錦感论、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至囊陡,卻和暖如春芳绩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背撞反。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工妥色, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人遏片。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓嘹害,卻偏偏與公主長得像撮竿,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子笔呀,可洞房花燭夜當晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容