在動態刪除v-for渲染的列表的過程當中,若是key指定爲index,則可能出現渲染錯亂的問題。好比,你明明刪了第一行,可是視圖上卻刪了第二行。vue
問題源於key的重複,當你刪了第一行,那麼第二行的key就變成了第一行的key,這兩個key是相同的。基於VirtualDOM的庫會把key相同的組件認做同一個組件,於是不會去更新視圖。app
也就是說,你刪了第一行,原本預期的第二行變成了第一行,結果變成由於key相同,最後第一行保持不變,反而是第二行消失了。ui
大部分時候咱們即便使用index做爲key,不會復現這個問題,這好像與咱們上述分析不符。可是事實上,「使用index做爲key而且不會出問題」這種場景,其實過程是這樣的:code
第一步:經過修改數據刪除第一行,數據變化引發vue去更新視圖,更新的過程當中發現key相同,最終第一行保持不變,反而是第二行消失。這是第一次render。get
第二步:第一行的VirtualDOM的確沒有變,可是第一行的組件的props變了,由原來第一行的props,變成了第二行的props,因爲props變化,第一行的組件須要使用新的props更新視圖,最終第一行變成了第二行的樣子。這是第二次render。io
也就是說,「使用index做爲key而且不會出問題」這種場景,是由於render了兩次,才最終達成了視圖的正確更新。響應式
若是你去刪除第一行的過程當中,只會觸發一次render,那麼就會復現問題。也就是說,若是每一行的組件,不依賴於任何「響應式」數據,那麼就不會有第二次render,問題就能復現!渲染
上述兩種狀況的DEMO:codesandbox.io/s/wonderful…數據
特殊狀況:若是列表中的組件,是簡單的文本節點,文本節點沒有props,那麼它會不會復現問題呢?db
答案是「不會」,Vue的Diff過程對文本節點有特殊處理,無論key一不同,都會用「新的文本節點」覆蓋「舊的文本節點」。
在使用非文本節點的組件,且這個組件沒有依賴於響應式的props,那麼此時對於列表的刪除操做會致使視圖錯亂。