Vue源碼之patch順口溜了解一下

經過同層的樹節點進行比較而非對樹進行逐層搜索遍歷的方式,因此時間複雜度只有O(n),是一種至關高效的算法node


同層級只作三件事:增刪改。

具體規則是:算法

  • new VNode不存在就刪;
  • old VNode不存在就增;
  • 都存在就 比較類型,類型不一樣直接替換、類型相同執行更新 

兩個VNode類型相同,就執行更新操做,包括三種類型操做:屬性更新PROPS、文本更新TEXT、子節點更新REORDER dom

  1. 若是新舊VNode都是靜態的,那麼只須要替換elm以及componentInstance便可。 spa

  2. 新老節點均有children子節點,則對子節點進行diff操做,調用updateChildren 3d

  3. 若是老節點沒有子節點而新節點存在子節點,先清空老節點DOM的文本內容,而後爲當前DOM節 code

    點加入子節點。 component

  4. 當新節點沒有子節點而老節點有子節點的時候,則移除該DOM節點的全部子節點。 cdn

  5. 當新老節點都無子節點的時候,只是文本的替換。 blog

⚠️  下面詮釋順口溜打開:src/core/vdom/patch.js文件

1、開始遊標<=結束遊標

首先oldStartVnode、oldEndVnodenewStartVnode、newEndVnode兩兩交叉比較(1-4) 接口

1. 舊頭對新頭,排着隊伍完後走

oldStartVnode newStartVnode  知足 sameVnode ,直接將該 VNode 節點進行 patchVnode 便可,不需再遍歷就完成了一次循環 




2. 舊尾對新尾,拉着尾巴順着走

當  oldEndVnode newEndVnode 知足 sameVnode ,直接將該 VNode 節點進行 patchVnode 便可,不需再遍歷就完成了一次循環 




3. 舊頭對新尾,按着新尾排排隊

若是 oldStartVnode newEndVnode 知足 sameVnode 。說明 oldStartVnode 已經跑到了 oldEndVnode 後面去了,進行 patchVnode 的同時還須要將真實DOM節點移動到 oldEndVnode 的後面。 




4. 舊尾對新頭,揪着舊尾前面走

若是 oldEndVnode newStartVnode 知足 sameVnode ,說明 oldEndVnode 跑到了 oldStartVnode 的前面,進行 patchVnode 的同時要將 oldEndVnode 對應DOM移動到 oldStartVnode 對應DOM的前面。 



5. 綜上皆無果,老實循環接個來

若是以上狀況均不符合,則在old VNode中找與 newStartVnode 知足 sameVnode vnodeToMove ,若 存在執行patchVnode,同時將 vnodeToMove 對應DOM移動到 oldStartVnode 對應的DOM的前面。 


固然也有可能 newStartVnode 在old VNode節點中找不到一致的key,或者是即使key相同卻不是 sameVnode ,這個時候會調用 createElm 建立一個新的DOM節點放到old VNode最前面。 



2、老遊標先結束oldStartIdx > oldEndIdx批量添加

當結束時 oldStartIdx > oldEndIdx ,這個時候舊的VNode節點已經遍歷完了,可是新的節點尚未。說 明瞭新的VNode節點實際上比老的VNode節點多,須要將剩下的VNode對應的DOM插入到真實DOM 中,此時調用 addVnodes (批量調用createElm接口)。 



3、新遊標先結束newStartIdx > newEndIdx批量刪除

當結束時 newStartIdx > newEndIdx 時,說明新的VNode節點已經遍歷完了,可是老的節點還有 剩餘,須要從文檔中刪 的節點刪除。 




相關文章
相關標籤/搜索