摘要:當(dāng)正在更新使用渲染的元素列表時,它默認使用就地更新的策略。如果數(shù)據(jù)項的順序被改變,將不會移動。避免對節(jié)點就地復(fù)用需要修改的節(jié)點位置沒有改變,是內(nèi)容更新了,這雖然提高了復(fù)用性能,但是往往在復(fù)雜的表單會導(dǎo)致狀態(tài)出現(xiàn)錯位。
當(dāng) Vue 正在更新使用 v-for 渲染的元素列表時,它默認使用“就地更新”的策略。如果數(shù)據(jù)項的順序被改變,Vue 將不會移動 DOM。 元素來匹配數(shù)據(jù)項的順序,而是就地更新每個元素,并且確保它們在每個索引位置正確渲染。這個類似 Vue 1.x 的 track-by="$index"。
這個默認的模式是高效的,但是只適用于不依賴子組件狀態(tài)或臨時 DOM 狀態(tài) (例如:表單輸入值) 的列表渲染輸出。
避免對節(jié)點「就地復(fù)用」
需要修改的節(jié)點位置沒有改變,是內(nèi)容更新了,這雖然提高了復(fù)用性能,但是往往在復(fù)雜的表單會導(dǎo)致狀態(tài)出現(xiàn)錯位。也不會產(chǎn)生過度效果
key相當(dāng)于每個vnode 的唯一id,我們可以依靠key,更快更精確的知道oldVnode中對應(yīng)的vnode節(jié)點。
帶key就不會使用就定復(fù)用了,在sameNode函數(shù)a.key===b.key對比中可以避免就地復(fù)用的情況。
我們可以利用key的唯一性來更快獲取到對應(yīng)節(jié)點,比遍歷更快。
什么是diff算法?要渲染真實的DOM的開銷很大,因為改變真實dom,會當(dāng)值整個dom樹的重繪和回流。我們需要渲染真實dom的時候往往會把生成一個虛擬節(jié)點 virtual DOM,當(dāng)virtual dom某個節(jié)點的數(shù)據(jù)改變后生成一個新的Vnode,然后將Vnode和oldVnode對比,當(dāng)然有不同的地方教就直接修改在真實DOM上,然后是oldVnode=Vnode
真實DOM
123
virtual DOM (虛擬DOM)
var Vnode={ tag:"div", children:[{ tag:"p",text:"123" }] }diff的比較方式
在同層級進行,不會跨層級比較
oldDOM
123
newDOM
2222
先對比DIV,發(fā)現(xiàn)兩個DIV不對等
查看DIV的子元素P、SPAN,發(fā)現(xiàn)不對等
查看P、SPAN沒有子元素,則移除P,增加SPAN
現(xiàn)在我們來看看在進行替換
對比節(jié)點函數(shù)function patch(oldVnode, vnode) { // 對比是否相等 if (sameVnode(oldVnode, vnode)) { patchVnode(oldVnode, vnode) } else { const oEl = oldVnode.el // 當(dāng)前oldVnode對應(yīng)的真實元素節(jié)點 let parentEle = api.parentNode(oEl) // 父元素 createELe(vnode) // 為vnode生成新的元素 if (parentEle !== null) { api.insertBefore(parentEle, vnode.el, api.nextSibling(oEl)) // 將新的元素添加到父元素中 api.removeChild(parentEle, oldVnode.el) // 移除以前的元素 } } return vnode }判斷兩者是否相同函數(shù)
function sameVnode(a, b) { return ( a.key === b.key && // 對比key a.tag === b.tag && // 對比標(biāo)簽名 a.isComment === b.isComment && // 是否為注釋節(jié)點 isDef(a.data) === isDef(b.data) && // 是否定義了data,或者其他屬性 sameInputType(a, b) //判斷是當(dāng)時 是否type相同 ) }
匹配規(guī)則
將Vnode的子節(jié)點Vch和oldVnode的子節(jié)點oldCh提取出來
oldCh和vCh各有兩個頭尾的變量StartIdx和EndIdx,它們的2個變量相互比較,一共有4種比較方式。如果4種比較都沒匹配,如果設(shè)置了key,就會用key進行比較,在比較的過程中,變量會往中間靠,一旦StartIdx>EndIdx表明oldCh和vCh至少有一個已經(jīng)遍歷完了,就會結(jié)束比較。
圖解
如果oldS和E匹配上了,那么真實DOM中的第一個節(jié)點會移到最后
如果oldE和S匹配上了,那么真實DOM中的最后一個節(jié)點會移到最后面,匹配上的兩個指針向中間移動
如果四種匹配都沒有一對成功成功的,那么遍歷oldChild,S挨個和他們匹配,匹配成功就在真實dom中講成功的節(jié)點移到最前面,如果沒有成功,那么犟S對應(yīng)的節(jié)點插入dom中對應(yīng)的olds位置,olds和s指正向中間移動
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/105965.html
摘要:解析第題第題為什么的和的中不能做異步操作解析第題第題京東下面代碼中在什么情況下會打印解析第題第題介紹下及其應(yīng)用。盡量減少操作次數(shù)。解析第題第題京東快手周一算法題之兩數(shù)之和給定一個整數(shù)數(shù)組和一個目標(biāo)值,找出數(shù)組中和為目標(biāo)值的兩個數(shù)。 引言 半年時間,幾千人參與,精選大廠前端面試高頻 100 題,這就是「壹題」。 在 2019 年 1 月 21 日這天,「壹題」項目正式開始,在這之后每個工...
摘要:當(dāng)一個組件沒有聲明任何時,這里會包含所有父作用域的綁定和除外,并且可以通過傳入內(nèi)部組件在創(chuàng)建高級別的組件時非常有用。 寫在前面 組件間的通信是是實際開發(fā)中非常常用的一環(huán),如何使用對項目整體設(shè)計、開發(fā)、規(guī)范都有很實際的的作用,我在項目開發(fā)中對此深有體會,總結(jié)下vue組件間通信的幾種方式,討論下各自的使用場景 文章對相關(guān)場景預(yù)覽 父->子組件間的數(shù)據(jù)傳遞 子->父組件間的數(shù)據(jù)傳遞 兄弟...
摘要:在寫法上最常見的兩種命名分別為和。下面列出了一些約定成俗的適用例子提交表單處理分頁頁數(shù)改變處理分頁每頁大小改變按下鍵場景二異步處理這里主要是指在寫數(shù)據(jù)層服務(wù)狀態(tài)管理中的命名,以及回調(diào)的命名規(guī)則。 JavaScript作為前端開發(fā)從業(yè)人員必須掌握的3大基礎(chǔ)知識中最重要的一環(huán),也是平是接觸時間最長、寫得最多的。在開發(fā)過程中必然會遇到命名的問題,你會詞窮、糾結(jié)、惆悵嗎?本文的出現(xiàn)相信能夠解決...
摘要:并總結(jié)經(jīng)典面試題集各種算法和插件前端視頻源碼資源于一身的文檔,優(yōu)化項目,在瀏覽器端的層面上提升速度,幫助初中級前端工程師快速搭建項目。 本文是關(guān)注微信小程序的開發(fā)和面試問題,由基礎(chǔ)到困難循序漸進,適合面試和開發(fā)小程序。并總結(jié)vue React html css js 經(jīng)典面試題 集各種算法和插件、前端視頻源碼資源于一身的文檔,優(yōu)化項目,在瀏覽器端的層面上提升速度,幫助初中級前端工程師快...
閱讀 3220·2021-11-19 09:40
閱讀 3013·2021-09-09 09:32
閱讀 801·2021-09-02 09:55
閱讀 1403·2019-08-26 13:23
閱讀 2421·2019-08-26 11:46
閱讀 1240·2019-08-26 10:19
閱讀 2069·2019-08-23 16:53
閱讀 1080·2019-08-23 12:44