1.虛擬 DOM
與頁(yè)面DOM元素對(duì)應(yīng)的對(duì)象轻纪。包含標(biāo)簽名、標(biāo)簽上的屬性催植、事件監(jiān)聽及其子元素肮蛹。本質(zhì)是一個(gè)JS對(duì)象。
2.優(yōu)點(diǎn)
- 減少DOM操作(次數(shù)和范圍)
虛擬DOM可以將多次操作合并為一次创南,比如添加1000個(gè)節(jié)點(diǎn)伦忠,不是一次次添加DOM節(jié)點(diǎn)。(次數(shù))
借助DOM diff將多余的操作省略稿辙,比如添加1000個(gè)節(jié)點(diǎn)昆码,根據(jù)DOM diff對(duì)比,其實(shí)只有10個(gè)是新的邻储。(范圍) - 跨平臺(tái)
虛擬DOM應(yīng)用在小程序未桥、iOS系統(tǒng)、安卓應(yīng)用
3.缺點(diǎn)
需要額外的創(chuàng)建函數(shù)來(lái)創(chuàng)建芥备,React使用createElement,Vue使用h函數(shù)舌菜,依賴打包工具構(gòu)建js文件
4.DOM diff
一個(gè)函數(shù)萌壳,運(yùn)行DOM的操作,對(duì)比新舊DOM 樹然后更新。
patches = patch(oldVNode,newVNode)
Tree diff
將新舊兩棵樹逐層進(jìn)行對(duì)比,查找更新節(jié)點(diǎn)
更新節(jié)點(diǎn)為組件-Component diff
更新節(jié)點(diǎn)為標(biāo)簽-Element diff
Component diff
如果節(jié)點(diǎn)是組件袱瓮,就先看組件類型
類型不同直接替換(刪除舊的)
類型相同則只更新屬性
然后深入組件做 Tree diff(遞歸)
Element diff
如果節(jié)點(diǎn)是原生標(biāo)簽缤骨,則看標(biāo)簽名
標(biāo)簽名不同直接替換,相同則只更新屬性
然后進(jìn)入標(biāo)簽后代做 Tree diff(遞歸)
5.DOM diff 的優(yōu)點(diǎn)
可以減少DOM操作
6.DOM diff 的問(wèn)題(key)
在同級(jí)節(jié)點(diǎn)對(duì)比有bug尺借,在同級(jí)節(jié)點(diǎn)更新時(shí)無(wú)法判斷是刪除了子節(jié)點(diǎn)p绊起,還是更新了子節(jié)點(diǎn)p,給他們添加唯一值key來(lái)標(biāo)識(shí)就可以解決燎斩。不要用index
來(lái)作為key值虱歪,在增刪DOM節(jié)點(diǎn)時(shí),index作為數(shù)組的下標(biāo)是不變的栅表,比如[1,2,3]
變成[1,3]
,下標(biāo)2始終存在笋鄙。