寫文章不容易,點個讚唄兄弟
專注 Vue 源碼分享,文章分爲白話版和 源碼版,白話版助於理解工作原理,源碼版助於瞭解內部詳情,讓我們一起學習吧
研究基於 Vue版本 【2.5.17】
如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下面關注公衆號也可以吧
終於到了最後一塊內容了!今天我們就來簡單概括一下 Diff,內容一點都不多哦,全是圖片
Diff 作爲 Vue 比較重要的一部分內容,還是非常有必要深入瞭解的
此篇文章就會分幾塊內容進行簡單闡述,不會出現任何的源碼,只是爲了幫助大家建立一種思路,瞭解下 Diff 的大概內容
1、Diff 的作用
2、Diff 的做法
3、Diff 的比較邏輯
4、簡單的例子
下面就開始我們的正文
Diff 作用
Diff 的出現,就會爲了減少更新量,找到最小差異部分DOM,只更新差異部分DOM就好了
這樣消耗就會小一些
數據變化一下,沒必要把其他沒有涉及的沒有變化的DOM 也替換了
Diff 做法
Vue 只會對新舊節點中 父節點是相同節點 的 那一層子節點 進行比較
也可以說成是
只有兩個新舊節點是相同節點的時候,纔會去比較他們各自的子節點
最大的根節點一開始可以直接比較
這也叫做 同層級比較,並不需要遞歸,雖然好像降低了一些複用性,也是爲了避免過度優化,是一種很高效的 Diff 算法
新舊節點是什麼
所有的 新舊節點 指的都是 Vnode 節點,Vue 只會比較 Vnode 節點,而不是比較 DOM
因爲 Vnode 是 JS 對象,不受平臺限制,所以以它作爲比較基礎,代碼邏輯後期不需要改動
拿到比較結果後,根據不同平臺調用相應的方法進行處理就好了
想了解 Vnode 更多信息可以轉到這篇文章 VNode - 源碼版
父節點是相同節點是什麼意思?
比如下圖出現的 四次比較(從 first 到 fouth),他們的共同特點都是有 相同的父節點
比如 藍色方的比較,新舊子節點的父節點是相同節點 1
比如 紅色方的比較,新舊子節點的父節點都是 2
所以他們纔有比較的機會
而下圖中,只有兩次比較,就是因爲在 藍色方 比較中,並沒有相同節點,所以不會再進行下級子節點比較
Diff 比較邏輯
Diff 比較的內核是 節點複用,所以 Diff 比較就是爲了在 新舊節點中 找到 相同的節點
這個的比較邏輯是建立在上一步說過的同層比較基礎之上的
所以說,節點複用,找到相同節點並不是無限制遞歸查找
比如下圖中,的確 舊節點樹 和 新節點樹 中有相同節點 6,但是然並卵,舊節點6並不會被複用
就算在同一層級,然而父節點不一樣,依舊然並卵
只有這種情況的節點會被複用,相同父節點 8
下面說說 Diff 的比較邏輯
1、能不移動,儘量不移動
2、沒得辦法,只好移動
3、實在不行,新建或刪除
比較處理流程是下面這樣
在新舊節點中
1、先找到 不需要移動的相同節點,消耗最小
2、再找相同但是需要移動的節點,消耗第二小
3、最後找不到,纔會去新建刪除節點,保底處理
比較是爲了修改DOM 樹
其實這裏存在 三種樹,一個是 頁面DOM 樹,一個是 舊VNode 樹,一個是 新 Vnode 樹
頁面DOM 樹 和 舊VNode 樹 節點一一對應的
而 新Vnode 樹則是表示更新後 頁面DOM 樹 該有的樣子
這裏把 舊Vnode 樹 和 新Vnode樹 進行比較的過程中
不會對這兩棵Vode樹進行修改,而是以比較的結果直接對 真實DOM 進行修改
比如說,在 舊 Vnode 樹同一層中,找到 和 新Vnode 樹 中一樣但位置不一樣節點
此時需要移動這個節點,但是不是移動 舊 Vnode 樹 中的節點
而是 直接移動 DOM
總的來說,新舊 Vnode 樹是拿來比較的,頁面DOM 樹是拿來根據比較結果修改的
如果你有點懵,我們就來就簡單說個例子
Diff 簡單例子
比如下圖存在這兩棵 需要比較的新舊節點樹 和 一棵 需要修改的頁面 DOM樹
第一輪比較開始
因爲父節點都是 1,所以開始比較他們的子節點
按照我們上面的比較邏輯,所以先找 相同 && 不需移動 的點
毫無疑問,找到 2
拿到比較結果,這裏不用修改DOM,所以 DOM 保留在原地
第二輪比較開始
然後,沒有 相同 && 不需移動 的節點 了
只能第二個方案,開始找相同的點
找到 節點5,相同但是位置不同,所以需要移動
拿到比較結果,頁面 DOM 樹需要移動DOM 了,不修改,原樣移動
第三輪比較開始
繼續,哦吼,相同節點也沒得了,沒得辦法了,只能創建了
所以要根據 新Vnode 中沒找到的節點去創建並且插入
然後舊Vnode 中有些節點不存在 新VNode 中,所以要刪除
於是開始創建節點 6 和 9,並且刪除節點 4 和 5
然後頁面就完成更新啦
怎麼樣,有沒有感興趣,感興趣就看源碼吧哈哈
後面的就會出源碼版啦
最後
鑑於本人能力有限,難免會有疏漏錯誤的地方,請大家多多包涵,如果有任何描述不當的地方,歡迎後臺聯繫本人,有重謝