前言
? ? 年初的時(shí)候看了一半厕宗,但是當(dāng)時(shí)換完工作就沒(méi)再繼續(xù)了。最近總算騰出空了灵巧,就從頭完整的梳理一遍
幾個(gè)疑問(wèn)
? ??1-為什么在根目錄掛載過(guò)后抬虽,在每個(gè)組件實(shí)例就都能拿到store中的數(shù)據(jù)了?
? ??2-為什么修改store中的數(shù)據(jù)能夠觸發(fā)vue組件的更新刑峡?
? ??3-它是怎么做模塊拆分的洋闽?
為什么在根目錄掛載過(guò)后,在每個(gè)組件實(shí)例就都能拿到store中的數(shù)據(jù)了
? ? vuex作為vue插件突梦,需要通過(guò)vue.use進(jìn)行注冊(cè)诫舅,在注冊(cè)過(guò)程中vue會(huì)把自身注入到向插件并調(diào)用插件的install進(jìn)行安裝
? ? 而這實(shí)際上是調(diào)用Vue.mixin混入了聲明周期鉤子beforeCreate,由于組件在初始化init過(guò)程中會(huì)有一次配置合并從vue構(gòu)造函數(shù)上讀取使用mixin保存的靜態(tài)屬性option宫患,所以每個(gè)組件都會(huì)執(zhí)行到vuexInit函數(shù)刊懈,自然也就能拿到store中的數(shù)據(jù)了
為什么修改store中的數(shù)據(jù)能夠觸發(fā)vue組件的更新
? ? 注冊(cè)完后,一般我們都是通過(guò)new Vuex.Store將vuex中的數(shù)據(jù)或公共API進(jìn)行掛載,它會(huì)執(zhí)行到resetStoreVM函數(shù)
? ? 既然是new Vue那就一定會(huì)執(zhí)行組件的初始化邏輯虚汛,所以呢匾浪,也必然會(huì)執(zhí)行initState方法進(jìn)行響應(yīng)式處理。所以基本可以斷定卷哩,它是借助響應(yīng)式實(shí)現(xiàn)的組件更新蛋辈。那么現(xiàn)在只需要看commit的過(guò)程中是怎么完成依賴收集和派發(fā)更新的即可
? ? 可以看到這里拿到我們?cè)趕tore中的mutations下定義的函數(shù)并執(zhí)行
? ? 當(dāng)然,這是被包裝處理過(guò)的函數(shù)殉疼,其實(shí)際上走的是這個(gè)
? ? 可以看到梯浪,這里對(duì)每一個(gè)key都進(jìn)行了一次遍歷,state[key]即是觸發(fā)依賴收集的關(guān)鍵
? ? 接著調(diào)用具體的函數(shù)瓢娜,如下挂洛,state.age = payload 即派發(fā)更新
vuex是如何做模塊拆分的
? ? 示例代碼如下
? ? 將代碼定位到new ModuleCollection(options),進(jìn)入眠砾,可以看到對(duì)modules遍歷并對(duì)register進(jìn)行遞歸虏劲,依次傳入moduleA和moduleB的內(nèi)容,并通過(guò)children建立父子關(guān)系
? ? ? ? 則褒颈,處理后的module形如:
{
? ? root:{
? ? ? ? children:{
? ??????????a:moduleA,
? ???????????b: moduleB
? ? ? ? }
? ? }
}
? ? ? ? 接著遞歸state通過(guò)Vue.set將子module中的state處理成響應(yīng)式數(shù)據(jù)