本文介紹了vue 虛擬dom的patch源碼分析,分享給大家,具體如下:
源碼目錄:src/core/vdom/patch.js
updateChildren
方法主要通過(guò)while
循環(huán)去對(duì)比2棵樹(shù)的子節(jié)點(diǎn)來(lái)更新dom
,通過(guò)對(duì)比新的來(lái)改變舊的,以達(dá)到新舊統(tǒng)一的目的。
通過(guò)一個(gè)例子來(lái)模擬一下:
假設(shè)有新舊2棵樹(shù),樹(shù)中的子節(jié)點(diǎn)分別為a,b,c,d
等表示,不同的代號(hào)代表不同的vnode
,如:
在設(shè)置好狀態(tài)后,我們開(kāi)始第一遍比較,此時(shí)oldStartVnode=a,newStartVnode=a;
命中了sameVnode(oldStartVnode,newStartVnode)
邏輯,則直接調(diào)用patchVnode(oldStartVnode,newStartVnode,insertedVnodeQueue)
方法更新節(jié)點(diǎn)a
,接著把oldStartIdx
和newStartIdx
索引分別+1,如圖:
更新完節(jié)點(diǎn)a
后,我們開(kāi)始第2遍比較,此時(shí)oldStartVnode=b,newEndVnode=b;
命中了sameVnode(oldStartVnode,newEndVnode)
邏輯,則調(diào)用patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue)
方法更新節(jié)點(diǎn)b
,接著調(diào)用canMove && nodeOps.insertBefore(parentElm, oldStartVnode.elm, nodeOps.nextSibling(oldEndVnode.elm))
,把節(jié)點(diǎn)b
移到樹(shù)的最右邊,最后把oldStartIdx
索引+1,newEndIdx
索引-1,如圖:
更新完節(jié)點(diǎn)b
后,我們開(kāi)始第三遍比較,此時(shí)oldEndVnode=d,newStartVnode=d;
命中了sameVnode(oldEndVnode, newStartVnode)
邏輯,則調(diào)用patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue)
方法更新節(jié)點(diǎn)d
,接著調(diào)用canMove && nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm)
,把d
移到c
的左邊。最后把oldEndIdx
索引-1,newStartIdx
索引+1,如圖:
更新完d
后,我們開(kāi)始第4遍比較,此時(shí)newStartVnode=e
,節(jié)點(diǎn)e
在舊樹(shù)里是沒(méi)有的,因此應(yīng)該被作為一個(gè)新的元素插入,調(diào)用createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm)
,后面執(zhí)行了nodeOps.insertBefore(parent, elm, ref)
方法把e
插入到c
之前,接著把newStartIdx
索引+1,如圖:
插入節(jié)點(diǎn)e
后,我們可以看到newStartIdx
已經(jīng)大于newEndIdx
了,while
循環(huán)已經(jīng)完畢。接著調(diào)用removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx)
刪除舊的c
,最終如圖:
updateChildren
通過(guò)以上幾步操作完成了舊樹(shù)子節(jié)點(diǎn)的更新,實(shí)際上只用了比較小的dom
操作,在性能上有所提升,并且當(dāng)子節(jié)點(diǎn)越復(fù)雜,這種提升效果越明顯。vnode
通過(guò)patch
方法生成dom
后,會(huì)調(diào)用mounted hook
,至此,整個(gè)vue
實(shí)例就創(chuàng)建完成了,當(dāng)這個(gè)vue
實(shí)例的watcher
觀察到數(shù)據(jù)變化時(shí),會(huì)兩次調(diào)用render
方法生成新的vnode
,接著調(diào)用patch
方法對(duì)比新舊vnode
來(lái)更新dom
.
上面是我整理給大家的,希望今后會(huì)對(duì)大家有幫助。
相關(guān)文章:
JQuery選中select組件被選中的值方法
vue.js中$set與數(shù)組更新方法_vue.js
vue與vue-i18n結(jié)合實(shí)現(xiàn)后臺(tái)數(shù)據(jù)的多語(yǔ)言切換方法
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com