1. 程式人生 > 其它 >【踩坑記】Vue 中使用 v-for 渲染元件,刪除第 N 個元件時渲染出錯問題

【踩坑記】Vue 中使用 v-for 渲染元件,刪除第 N 個元件時渲染出錯問題

技術標籤:前端雜文vue

發現問題

最近在做檔案多標籤頁編輯的功能,使用了 v-for 來載入多個已開啟檔案的編輯器,並且在標籤上有關閉按鈕可以關閉指定的已開啟的檔案編輯器。

父元件頁面渲染如下:

<template v-for="(file, index) in visitedFiles">
	<editor-component v-show="currFile.name === file.name" :key="`editor${index}`" :file="file" @close
="closeFile(file)"/>
</template>

當前檢視的是第二個檔案,而當我選擇關閉第一個檔案標籤時,預期是第一個檔案關閉,但編輯器正確顯示第二個檔案的內容。但是實際操作時,關閉第一個標籤,第二個檔案編輯器的內容會變為關閉的那個檔案。
在這裡插入圖片描述

思考

第一反應是覺得 Vue 的渲染出了問題。用 v-for 進行的 DOM 元素渲染,當刪除某個標籤頁時,因為這個刪除的標籤頁跟其他標籤頁的 DOM 物件結構相同,Vue 的 DIFF 演算法認為只需要更新元件的屬性而不需要更新元件的渲染從而導致顯示的內容不正確。

但上面只是一個想法,還需要通過各種 search 去了解一下真正的原因。

原因

這個問題是因為 Vue v-for 的“就地複用策略”引發的。當 Vue 更新用 v-for 渲染的元素列表時,預設情況下,它使用“就地複用”策略。 如果資料項的順序已更改,則 Vue 不會移動 DOM 元素以使其與項的順序匹配,而是會在適當位置修補每個元素,並確保其反映應在該特定索引處呈現的內容。

解決方法

將 :key="`editor${index}`" 改為 :key="file.name" 

更具體的解釋:為什麼 Vue 中不要用 index 作為 key?