<em id="09ttv"></em>
    <sup id="09ttv"><pre id="09ttv"></pre></sup>
    <dd id="09ttv"></dd>

        • Vue源碼剖析(三)patch和Diff算法

          2019-10-30    seo達(dá)人

          Patch和Diff算法

          網(wǎng)上看了好多的博客和源碼教程,感覺很多仔細(xì)的地方?jīng)]有說清,而且在一些復(fù)雜的部分加了好多的描述,所以就想自己也寫下心得, 方便自己, 方便他人,有興趣的同學(xué)可以關(guān)注我的github里面有我之前一些博文 github/193Eric



          我們知道的,在數(shù)據(jù)更改后,會觸發(fā)getter,然后通過dep.notify()來通知watcher觸發(fā)update進(jìn)而更新視圖,最終是通過Diff算法來對比新老Vnode的差異,并把差異更新到Dom視圖上



          Diff

          我們知道的,Virtual DOM是一顆樹,而diff算法主要把兩顆樹進(jìn)行對比,找出之間的差異,來渲染頁面



          diff 算法是通過同層的樹節(jié)點進(jìn)行比較而非對樹進(jìn)行逐層搜索遍歷的方式,所以時間復(fù)雜度只有 O(n),是一種相當(dāng)?shù)乃惴?br />


          1.調(diào)用patch函數(shù)比較Vnode和OldVnode,如果不一樣直接return Vnode即將Vnode真實化后替換掉DOM中的節(jié)點



          2.如果OldVnode和Vnode值得進(jìn)一步比較則調(diào)用patchVnode方法進(jìn)行進(jìn)一步比較,分為以下幾種情況:



          Vnode有子節(jié)點,但是OldVnode沒有,則將Vnode的子節(jié)點真實化后添加到真實DOM上



          Vnode沒有子節(jié)點,但是OldVnode上有,則將真實DOM上相應(yīng)位置的節(jié)點刪除掉



          Vnode和OldVnode都有文本節(jié)點但是內(nèi)容不一樣,則將真實DOM上的文本節(jié)點替換為Vnode上的文本節(jié)點



          Vnode和OldVnode上都有子節(jié)點,需要調(diào)用updateChildren函數(shù)進(jìn)一步比較



          updateChildren比較規(guī)則



          提取出Vnode和OldVnode中的子節(jié)點分別為vCh和OldCh,并且提出各自的起始和結(jié)尾變量標(biāo)記為 oldS oldE newS newE



          如果是oldS和newE匹配上了,那么真實dom中的第一個節(jié)點會移到最后



          如果是oldE和newS匹配上了,那么真實dom中的最后一個節(jié)點會移到最前,匹配上的兩個指針向中間移動



          如果都沒有,在沒有key的情況下直接在DOM的oldS位置的前面添加newS,同時newS+1。在有key的情況下會將newS和Oldch上的所有節(jié)點對比,如果有相同的則移動DOM并且將舊節(jié)點中這個位置置為null且newS+1。如果還沒有則直接在DOM的oldS位置的前面添加newS且newS+1

          直到出現(xiàn)任意一方的start>end,則有一方遍歷結(jié)束,整個比較也結(jié)束



          updateChildren例子:



          假設(shè):



          真實dom為 A、B、C

          oldDom為 A1、B1、C1

          newDom為 A2、D2、C2、B2



          先確定oldS = A1 ; oldE = C1; newS = A2; newE = B2



          先對比oldS和newS,oldE和newE,發(fā)現(xiàn)oldS = newS 所以真實dom的A固定不動。排序為 A、B、C

          然后oldS = B1 ; oldE = C1; newS = D2; newE = B2



          對比發(fā)現(xiàn) oldS = newE , 所以真實dom,B要插入到后面去



          真實dom排序為:A、C、B



          然后oldS = C1; oldE = C1; newS = D2; newE = B2



          對比發(fā)現(xiàn)兩兩都不對等,所以走第三步。

          假設(shè)有key存在,所以newS直接和oldDom里面的所有節(jié)點對比,發(fā)現(xiàn)沒有存在,然后插入到oldS前面,且newS+1

          真實dom排序為:A、D、C、B

          然后重新開始,oldS++ > oldE-- ,結(jié)束了。



          這就是updateChildren,之后就是一直遍歷,運行updateChildren直到?jīng)]有


          日歷

          鏈接

          個人資料

          存檔

          青青草国产97免久久费观看| 国产亚洲精久久久久久无码| 亚洲国产成人精品91久久久| 久久久国产亚洲精品| 国产精品美女久久久久| 久久精品一区二区影院| 亚洲AV无一区二区三区久久| 久久香蕉一级毛片| 久久九九兔免费精品6| 精品久久久久久无码免费| 久久w5ww成w人免费| 久久毛片一区二区| 久久99精品久久久久久不卡| 精品永久久福利一区二区| 精品久久久久成人码免费动漫 | 久久91这里精品国产2020| 精品久久久无码21p发布| 色偷偷91久久综合噜噜噜噜| 人人狠狠综合久久亚洲88| 久久综合综合久久综合| 久久无码专区国产精品发布 | 久久久国产打桩机| 亚洲精品无码久久久久AV麻豆| 99久久婷婷国产综合精品草原| 久久精品午夜一区二区福利 | 久久精品中文字幕大胸| 久久久久无码精品国产app| 狠狠色婷婷久久一区二区三区| 久久婷婷激情综合色综合俺也去| 亚洲欧洲日产国码无码久久99| 婷婷国产天堂久久综合五月| 要久久爱在线免费观看| 亚洲精品综合久久| 精品伊人久久大线蕉色首页| 精品国产乱码久久久久软件| 亚洲精品无码久久一线| a高清免费毛片久久| 狠狠色丁香久久综合婷婷| 国产精品午夜久久| 久久久久综合国产欧美一区二区| 青青草原综合久久大伊人导航|