站長資訊網
        最全最豐富的資訊網站

        vue中為什么v-for指令的 key 值不能是 index?

        vue中使用v-for時為什么不能用index作為key?下面本篇文章給大家介紹一下 v-for 的 key 值不能是 index 的原因,希望對大家有所幫助!

        vue中為什么v-for指令的 key 值不能是 index?

        為什么 v-for 的 key 值不能是 index?

        很多人一說起這道老生常談的面試題,馬上就開始滔滔不絕地講述 虛擬DOMdiff算法 了。

        講這些沒問題,但如果是我,一定先講 v-for 的 key 值寫成 index 會造成的問題,再講原理。

        曾經我寫 v-for, key 值永遠都是 index,直到有一天,我這么寫造成了線上bug

        來看一下我的線上bug演示吧:

        父組件代碼 <Child   v-for="(item, index) in list"   :key="index"   :count="item.count"   :name="item.name"   @delete="handleDelete(index)" />  list: [     {       count: 1,       name: '第1個元素'     },     {       count: 2,       name: '第2個元素'     },     {       count: 3,       name: '第3個元素'     }   ]    handleDelete(index) {   this.list.splice(index, 1) },

        vue中為什么v-for指令的 key 值不能是 index?

        如代碼和gif演示,點擊刪除第2個元素,看上去似乎一切正常。

        等一下,第三個元素的count值居然變成了2,wtf!!!

        驚得我又去看了遍子組件的代碼

        子組件 <div>   <span>{{ name }}</span>   count值為:{{ innerCount }}   <button @click="$emit('delete')">-</button> </div>  props: {   count: {     type: Number,     default: 0   },   name: {     type: String,     default: ''   } }, data() {   return {     innerCount: this.count   }  }

        感覺也沒什么不對的啊。

        不信邪,我又多創建了點元素來刪除,還試了下排序:

        vue中為什么v-for指令的 key 值不能是 index?

        果然,不光刪除元素有問題,排序也有問題。

        把 key 值改成 item.name 再試一下。

        <Child   v-for="(item, index) in list"   :key="item.name"   :count="item.count"   :name="item.name"   @delete="handleDelete(index)" />

        vue中為什么v-for指令的 key 值不能是 index?

        正常了。

        這樣看來,在 v-for 里把 key 值寫成 index,非常危險啊。

        在查閱了 vue 官方文檔之后,我終于明白了原因:

        當 Vue 正在更新使用 v-for 渲染的元素列表時,它默認使用“就地更新”的策略。如果數據項的順序被改變,Vue 將不會移動 DOM 元素來匹配數據項的順序,而是就地更新每個元素,并且確保它們在每個索引位置正確渲染。

        這個默認的模式是高效的,但是只適用于不依賴子組件狀態或臨時 DOM 狀態 (例如:表單輸入值) 的列表渲染輸出

        不依賴子組件狀態

        子組件里有一行很關鍵的代碼

        data() {   return {     innerCount: this.count   }  }

        子組件內部定義了 innerCount,這樣子組件就有了自己的狀態,按照官方文檔的說明,這種情況下不能把 index 作為 key 值。

        臨時 DOM 狀態

        <div v-for="(item, index) in list1" :key="index">   <input type="text" />   <button @click="delClick(index)">刪除</button> </div>

        vue中為什么v-for指令的 key 值不能是 index?

        刪除了第2項,但是第3項在表單中的3變成了2,跟上面依賴子組件狀態的例子是一樣的。

        總結

        寫列表渲染時, 依賴子組件狀態或臨時 DOM 狀態的情況,如果有 刪除、增加、排序這樣的功能,不要把 index 作為 key。

        事實上,寫列表渲染時,永遠不要把 index 做為 key,key 一定要是唯一標識。

        至于原因,就要理解 diff 算法之后才能明白了。

        待解答問題:

        • key 為什么不能寫成隨機數或時間戳?
        • key 為什么要是唯一標識?

        別著急,立了個寫100個 vue 問題相關文章的 flag 呢,后面的文章再慢慢分析。

        希望我的 vue 系列文章能對前端路上的你有幫助~

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 亚洲日韩欧美制服精品二区| 欧美日韩人妻精品一区二区在线| 亚洲国产午夜中文字幕精品黄网站 | 国产精品禁18久久久夂久| 久草欧美精品在线观看| 欧美精品一区二区三区视频| 久久精品麻豆日日躁夜夜躁| 亚洲国产精品一区二区三区久久| 国产精品视频色视频| 久久精品这里热有精品| 国产精品人人爽人人做我的可爱| 无码精品A∨在线观看| 亚洲欧美精品一区久久中文字幕| 精品国产一区二区22| 99久久国产综合精品网成人影院| 国产91大片精品一区在线观看 | 午夜精品视频在线| 99精品视频在线观看免费| 久久国产免费观看精品3| 亚洲av永久无码精品秋霞电影影院| 国产在线精品福利大全| 国产福利电影一区二区三区,亚洲国模精品一区 | 国产人妖乱国产精品人妖| 人妻AV一区二区三区精品| 亚洲性日韩精品一区二区三区| 久久精品中文字幕第23页| 精品久久久久久国产牛牛app| 国产精品国产三级在线高清观看| 99热这里只有精品6国产免费| 91精品无码久久久久久五月天| 亚洲综合精品香蕉久久网97| 亚洲一区精品中文字幕| 国产精品1024视频| 黑人巨大精品欧美一区二区| 久久99国产精品成人欧美| 欧美在线精品一区二区三区| 香港aa三级久久三级老师2021国产三级精品三级在 | 国精品午夜福利视频不卡| 精品人人妻人人澡人人爽人人| 久久青青草原精品国产| 久久久久99精品成人片试看|