什么情況下Vue使用index作為key會出問題(轉)


結論

在使用非文本節點的組件,且這個組件沒有依賴於響應式的props,此時使用index作為key,那么此時對於列表的刪除操作會導致視圖錯亂。

 

 

背景

在動態刪除v-for渲染的列表的過程中,如果key指定為index,則可能出現渲染錯亂的問題。比如,你的列表有兩行,你明明刪了第一行,結果卻是第二行消失了。

 

解析

問題源於key的重復,假設你的列表有兩行,當你刪了第一行,那么第二行的key就變成了第一行的key,這兩個key是相同的。基於VirtualDOM的庫會把key相同的組件認作同一個組件,因而不會去更新視圖。

也就是說,你刪了第一行,本來預期的第二行變成了第一行,結果變成因為key相同,最后第一行保持不變,反而是第二行消失了。

 

 

為什么我沒有復現

大部分時候我們即使使用index作為key,不會復現這個問題,這好像與我們上述分析不符。但是事實上,“使用index作為key並且不會出問題”這種場景,其實過程是這樣的:

  1. 第一步:通過修改數據刪除第一行,數據變化引起vue去更新視圖,更新的過程中發現key相同,最終第一行保持不變,反而是第二行消失。這是第一次render。

  2. 第二步:第一行的VirtualDOM的確沒有變,但是第一行的組件的props變了,由原來第一行的props,變成了第二行的props,由於props變化,第一行的組件需要使用新的props更新視圖,最終第一行變成了第二行的樣子。這是第二次render。

也就是說,“使用index作為key並且不會出問題”這種場景,是因為render了兩次,才最終達成了視圖的正確更新。

 

那什么時候可以復現

如果你去刪除第一行的過程中,只會觸發一次render,那么就會復現問題。也就是說,如果每一行的組件,不依賴於任何“響應式”數據,那么就不會有第二次render,問題就能復現!

 

上述兩種情況的DEMO:codesandbox.io/s/wonderful…

 

特殊情況:如果列表中的組件,是簡單的文本節點,文本節點沒有props,那么它會不會復現問題呢?

答案是“不會”,Vue的Diff過程對文本節點有特殊處理,不管key一不一樣,都會用“新的文本節點”覆蓋“舊的文本節點”。

結論

在使用非文本節點的組件,且這個組件沒有依賴於響應式的props,那么此時對於列表的刪除操作會導致視圖錯亂。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM