vue的diff演算法理解

2021-10-17 18:38:42 字數 1820 閱讀 8126

diff演算法作用:

用來修改dom的一小段,不會引起dom樹的重繪
diff演算法實現的原理:
diff演算法將virtual dom的某個節點資料改變後生成的新的vnode與舊節點進行比較,並替換為新的節點,具體過程就是呼叫patch方法,比較新舊節點,一邊比較一邊給真實的dom打補丁進行替換
function

patch

(oldvnode, vnode)

else

}// some code

return vnode

}function

samevnode

(a, b)

function

patchvnode

(oldvnode, vnode)

else

else

if(ch)

else

if(oldch)}}

function

updatechildren

(parentelm, oldch, newch, insertedvnodequeue, removeonly)

while

(oldstartidx <= oldendidx && newstartidx <= newendidx)

elseif(

isundef

(oldendvnode)

)elseif(

samevnode

(oldstartvnode, newstartvnode)

)elseif(

samevnode

(oldendvnode, newendvnode)

)elseif(

samevnode

(oldstartvnode, newendvnode)

)elseif(

samevnode

(oldendvnode, newstartvnode)

)else

else

else

} newstartvnode = newch[

++newstartidx]}}

if(oldstartidx > oldendidx)

else

if(newstartidx > newendidx)

}

具體過程詳解:
1:在採用diff演算法進行新舊節點進行比較的時候,比較是按照在同級進行比較的,不會進行跨級比較

2:當資料發生改變的時候,set方法會呼叫dep.notify通知所有的訂閱者watcher,訂閱者會呼叫patch函式給響應的dom進行打補丁,從而更新真實的檢視

3:patch函式接受兩個引數,第乙個是舊節點,第二個是新節點,首先判斷兩個節點是否值得比較,值得比較則執行patchvnode函式,不值得比較則直接將舊節點替換為新節點。如果兩個節點一樣就直接檢查對應的子節點,如果子節點不一樣就說明整個子節點全部改變不再往下對比直接進行新舊節點的整體替換

4:patchvnode函式:找到真實的dom元素;判斷新舊節點是否指向同乙個物件,如果是就直接返回;如果新舊節點都有文字節點,那麼直接將新的文字節點賦值給dom元素並且更新舊的節點為新的節點;如果舊節點有子節點而新節點沒有,則直接刪除dom元素中的子節點;如果舊節點沒有子節點,新節點有子節點,那麼直接將新節點中的子節點更新到dom中;如果兩者都有子節點,那麼繼續呼叫函式updatechildren

5:updatechildren函式:抽離出新舊節點的所有子節點,並且設定新舊節點的開始指標和結束指標,然後進行兩輛比較,從而更新dom(調整順序或者插入新的內容 結束後刪掉多餘的內容)

vue的diff演算法

1.當資料發生變化時,vue是怎麼更新節點的?渲染真實dom的開銷很大,比如我們修改了某個資料,如果直接渲染到真實dom會引起整個dom樹的重繪和重排,有沒有可能我們只更新我們修改的那一小塊dom而不更新整個dom呢?diff演算法可以幫助我們。我們根據真實dom生成乙個虛擬dom,當虛擬dom某個...

A 演算法理解

廣度優先 bfs 和深度優先 dfs 搜尋 深度優先搜尋,用俗話說就是不見棺材不回頭。演算法會朝乙個方向進發,直到遇到邊界或者障礙物,才回溯。一般在實現的時候,我們採用遞迴的方式來進行,也可以採用模擬壓棧的方式來實現。如下圖,s代表起點,e代表終點。我們如果按照右 下 左 上這樣的擴充套件順序的話,...

詳解vue的diff演算法

前言先來了解幾個點 1.當資料發生變化時,vue是怎麼更新節點的?要知道渲染真實dom的開銷是很大的,比如有時候我們修改了某個資料,如果直接渲染到真實dom上會引起整個dom樹的重繪和重排,有沒有可能我們只更新我們修改的那一小塊dom而不要更新整個dom呢?diff演算法能夠幫助我們。我們先根據真實...