走一遍Vue渲染更新的流程

前言

在這裏插入圖片描述
這個圖估計大家都看爛了,這篇文章就從這幅圖講起。

概覽

首先new Vue()之後會進入初始化階段,初始化的東西有很多,如我們的常見的生命週期,事件,屬性與狀態,計算屬性與watch,並實現數據的響應式。

初始化完成之後就是掛載階段,如果是使用template模板並且處於運行時編譯的狀態,那麼會進行編譯階段。

編譯階段由parse, optimize, generate組成,分別用來解析模板語法並生成AST,標記靜態節點以優化,將AST轉化爲render function string的過程,這樣就準備完成了渲染VNode所需的render function。

更新階段主要由響應式支撐,當render function string時,因爲會讀取所需對象,會觸發getter函數(2或3)進行依賴收集,隨後修改對象時,setter會通知之前依賴收集的每一個watcher,讓他們調用update來更新視圖。

再回到render function string那一步,它最終會轉化爲VNode並再度生成真實DOM Node,而響應式更新後會通過patch比較,使用Diff算法統一將更新打包到真實的DOM Tree上。

這樣就走完了整個Vue的流程。

響應式之前寫過幾篇文章了,這裏不再贅述,剩下的篇幅主要說一下Vue的Diff、nextTick和Vuex。

Diff

diff算法可以說是入門的前端基本都知道卻又都陌生的內容,知道在於它很好理解,就是比較出兩個VNode DOM Tree之間的差異;陌生在於所謂的編輯距離和之後各式各樣的優化實在難以讓人讀進去,在我看來可能直接寫編輯距離是難了點,但是優化確實我們不得不知道的內容。

同時diff算法很多都有,React的Diff分爲三個維度,Tree Diff,Component Diff, 以及Element Diff。這個之前文章也講過,不在展開。

Vue的Diff稍有不同,首先和Tree Diff一樣也是同層節點之間的對比,類型不同也會直接移除等。但是對於列表元素的對比,React是直接收集key的依賴,根據key值去進一步做增刪。但是Vue採用的首尾對比加key值依賴結合的辦法。

nextTick

我們知道對於React來說,當setState之後,他會根據isBatchUpdate判斷是不是需要同步更新狀態,一般來說,狀態的改變是會收集到dirtyComponent之中,是一種異步更新的體現。這種收集變化異步更新的機制並不只是React實現,Vue自然也需要。然而某些情況下我們確實需要立刻拿到更新的值,在React中,我們可以使用setState的第二個函數參數拿到。而在Vue中發揮這個作用的就是nextTick了。

詳解一下,當某個數據的setter方法觸發之後,watcher對象會被推進一個隊列中,在下一次tick時這些隊列中的數據會被拿出來統一Run,這個tick即爲我們需要的nextTick,目的是在微任務中創建一個事件,保證當前調用棧執行完畢後採取執行這個事件。而我們手動調用的root.$nextTick也是會在這個隊列中添加一個回調,在下一次tick時執行。

Vuex

我們知道Vuex其實是flux或Redux思想與Vue結合的本地化產物,那麼它的思想和Redux很類似,就是創建一個全局的store,以props的形式接收參數。只不過因爲響應式的存在,Vuex不需要Redux手動connect等。

function vuexInit () {
    const options = this.$options;
    if (options.store) {
        this.$store = options.store;
    } else {
        this.$store = options.parent.$store;
    }
}

上面方法意味着噹噹前是根節點的話直接把options.store賦值給this.$store,否則就從父節點裏面找。保證無論是Vue根節點還是組件都可以訪問store的實例。

總結

沒啥總結的了,好好寫

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章