首頁 >web前端 >Vue.js >vue中為什麼v-for指令的 key 值不能是 index?

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

青灯夜游
青灯夜游轉載
2022-01-22 15:05:004018瀏覽

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: &#39;第1个元素&#39;
    },
    {
      count: 2,
      name: &#39;第2个元素&#39;
    },
    {
      count: 3,
      name: &#39;第3个元素&#39;
    }
  ]
  
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(&#39;delete&#39;)">-</button>
</div>

props: {
  count: {
    type: Number,
    default: 0
  },
  name: {
    type: String,
    default: &#39;&#39;
  }
},
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 系列文章能對前端路上的你有幫助~

【相關推薦:vue.js影片教學

#

以上是vue中為什麼v-for指令的 key 值不能是 index?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除