摘要:不清楚的可以查看此文章的源代碼前言在或者內(nèi),每一個(gè)都有一個(gè)唯一來(lái)標(biāo)識(shí),通常是框架自動(dòng)處理,但是在循環(huán)內(nèi)必須由開(kāi)發(fā)者指定。所以以下解讀我就是用這個(gè)來(lái)代表內(nèi)的對(duì)象。
不清楚virtual-dom的可以查看此文章
list-diff的源代碼
前言:在vue或者react內(nèi),每一個(gè)VNode都有一個(gè)唯一key來(lái)標(biāo)識(shí),通常是框架自動(dòng)處理,但是在循環(huán)內(nèi)必須由開(kāi)發(fā)者指定。所以以下解讀我就是用這個(gè)key來(lái)代表list內(nèi)的對(duì)象。
我們并不需要真的達(dá)到最小的操作,我們只需要優(yōu)化一些比較常見(jiàn)的移動(dòng)情況,犧牲一定DOM操作,讓算法時(shí)間復(fù)雜度達(dá)到線性的(O(max(M, N))
方法入口let diff = (oldList, newList) => { let moves = []; // 邏輯處理 return moves; }
由上可以看出,diff函數(shù)返回的是將舊數(shù)組轉(zhuǎn)換成新數(shù)組的步驟
下面我會(huì)詳細(xì)說(shuō)明中間的邏輯處理步驟
oldList = [ A, B, C, D]; newList = [ E ,C, D, B];第一步,兩個(gè)數(shù)組取交集,找到需要?jiǎng)h除的item
var simulateList = []; oldList.forEach((item, index) => { // 此item存在于newList內(nèi) if (newList.indexOf(item) !== -1) { simulateList.push(item) } else { moves.push({ type: "remove", index: index }) } }); // 程序運(yùn)行結(jié)束,此時(shí)simulateList 就是oldList與newList的交集,并且是按oldList的順序進(jìn)行排序的 // 此時(shí)simulateList的值為[ B, C, D] // 此時(shí)moves的值為[{type:"remove",index:0}],標(biāo)識(shí)將下標(biāo)為0的item從oldList內(nèi)刪除,即刪除A第二步,同步遍歷newList和simulateList
newList = [E,C,D,B]; simulateList= [B,C,D]; // i與j分別是newList與simulateList的下標(biāo) // newList E 與 simulateList B 比較,E 不等于 B 且 E 不存在于simulateList中,則insert E // 此時(shí)i=0;j=0; moves = [ {type:"remove",index:0}, {type:"insert",index:0,item:E} ]; i++; // newList C 與 simulateList B 比較,C 不等于 B 且 simulateList B 的下一個(gè)為 C,則remove B // i=1;j=0; moves = [ {type:"remove",index:0}, {type:"insert",index:0,item:E}, {type:"remove",index:1} ] i++; j++; // 4. newList D 與 simulateList D 比較,相等則進(jìn)入下一步比較 i++; j++; // 5. newList B,此時(shí)simulateList 已經(jīng)比較完了,則 insert B // i=3;j=2; moves = [ {type:"remove",index:0}, {type:"insert",index:0,item:E}, {type:"remove",index:1}, {type:"inser", item: B, index: 3} ]
最終返回的數(shù)據(jù)如上所示,按照這個(gè)步驟,可以將oldList轉(zhuǎn)變?yōu)閚ewList,通常情況下對(duì)于list的改變主要集中在,刪除數(shù)據(jù),或者新增數(shù)據(jù),將list數(shù)據(jù)全部打亂的情況極少,所以以上算法基本滿足我們的需要。
由上可以看出唯一key的重要性,在用vue或者react寫(xiě)list的時(shí)候,務(wù)必要使用唯一的固定值作為可以,杜絕用數(shù)組下標(biāo)作為key的寫(xiě)法。
第一次寫(xiě)文章,不足之處還請(qǐng)海涵
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/98704.html
摘要:所以只針對(duì)同層級(jí)節(jié)點(diǎn)做比較,將復(fù)雜度的問(wèn)題轉(zhuǎn)換成復(fù)雜度的問(wèn)題。 React系列 React系列 --- 簡(jiǎn)單模擬語(yǔ)法(一)React系列 --- Jsx, 合成事件與Refs(二)React系列 --- virtualdom diff算法實(shí)現(xiàn)分析(三)React系列 --- 從Mixin到HOC再到HOOKS(四)React系列 --- createElement, ReactElem...
摘要:虛擬原理流程簡(jiǎn)單概括有三點(diǎn)用模擬樹(shù),并渲染這個(gè)樹(shù)比較新老樹(shù),得到比較的差異對(duì)象把差異對(duì)象應(yīng)用到渲染的樹(shù)。下面是流程圖下面我們用代碼一步步去實(shí)現(xiàn)一個(gè)流程圖用模擬樹(shù)并渲染到頁(yè)面上其實(shí)虛擬,就是用對(duì)象結(jié)構(gòu)的一種映射,下面我們一步步實(shí)現(xiàn)這個(gè)過(guò)程。 背景 大家都知道,在網(wǎng)頁(yè)中瀏覽器資源開(kāi)銷最大便是DOM節(jié)點(diǎn)了,DOM很慢并且非常龐大,網(wǎng)頁(yè)性能問(wèn)題大多數(shù)都是有JavaScript修改DOM所引起的...
摘要:但是實(shí)際開(kāi)發(fā)中,整個(gè)文檔樹(shù)中和標(biāo)簽基本不會(huì)有太大的改動(dòng)。在測(cè)試中,不難發(fā)現(xiàn)其實(shí)已經(jīng)很快了,但是速度會(huì)比較慢,所以這里留下了一個(gè)待優(yōu)化的點(diǎn)就是。 如何實(shí)現(xiàn) virtual-dom 0. 什么是 vnode 相信大部分前端同學(xué)之前早已無(wú)數(shù)次聽(tīng)過(guò)或了解過(guò) vnode(虛擬節(jié)點(diǎn)),那么什么是 vnode? vnode 應(yīng)該是什么樣的?如果不使用前端框架,我們可能會(huì)寫(xiě)出這樣的頁(yè)面: ...
摘要:具體代碼如下,,下面,我們來(lái)簡(jiǎn)單介紹下這個(gè)排序算法檢查和中的是否擁有字段,如果沒(méi)有,直接返回的數(shù)組。通過(guò)上面這個(gè)排序算法,我們可以得到一個(gè)新的的數(shù)組。 概述 本文通過(guò)對(duì)virtual-dom的源碼進(jìn)行閱讀和分析,針對(duì)Virtual DOM的結(jié)構(gòu)和相關(guān)的Diff算法進(jìn)行講解,讓讀者能夠?qū)φ麄€(gè)數(shù)據(jù)結(jié)構(gòu)以及相關(guān)的Diff算法有一定的了解。 Virtual DOM中Diff算法得到的結(jié)果如何映...
閱讀 1255·2023-04-25 18:57
閱讀 2142·2023-04-25 16:28
閱讀 3947·2021-11-24 09:39
閱讀 3641·2021-11-16 11:45
閱讀 1831·2021-10-13 09:40
閱讀 1272·2019-08-30 15:52
閱讀 1725·2019-08-30 10:57
閱讀 671·2019-08-29 16:55