1. 程式人生 > 其它 >list vue 刪除後頁面渲染_43. Vue 中繫結 key 屬性的作用是什麼

list vue 刪除後頁面渲染_43. Vue 中繫結 key 屬性的作用是什麼

技術標籤:list vue 刪除後頁面渲染

在解釋繫結 key 值的作用前,我們先來看一個示例:

<div id="app">  <key-test v-for="(item, index) in list">    <button @click="remove(index)">刪除{{item}}button>  key-test>  <button @click="add">新增button>div><script>  Vue.component('key-test', {    template:      ',    data: function () {      return {        value: Date.now()      }    }  })  new Vue({    el: '#app',    data: {      list: [],      index: 1    },    methods: {      add: function () {        this.list.push(this.index++)      },      remove: function (index) {        this.list.splice(index, 1)      }    }  })script>

執行效果如下:

79dcc758f295eade55f840320c8be413.gif

從執行效果中可以看到,當點選第一行刪除按鈕時,第一行的文字框內容並沒有被刪除,而是將最後一行中的文字框內容刪除了,為什麼會是這種情況呢?

這是因為v-for 更新已渲染過的元素列表時,它預設使用“就地複用”的策略,如果資料項的順序發生了改變,Vue 不會移動 DOM 元素來匹配資料項的順序,而是簡單複用此處的元素。

來分析一下上述執行結果的原因:

當點選三次“新增”按鈕時,頁面中會渲染三次 元件內容,同時,父元件中的 list 陣列元素值變為 [1, 2, 3]。當點選第一行中的刪除按鈕時,呼叫 remove() 方法將 list 陣列中的第一個元素刪除,則 list

陣列變為 [2, 3],然後檢視中重新使用 v-for 渲染,按鈕上的資料依賴於 list 中的元素值,所以被刪除掉。由於之前的檢視中已渲染過 元件三次,而 元件中的狀態資料不受 list 陣列中刪除元素的影響,根據“就地複用”策略, 被就地複用。但陣列中現在只有兩個元素,也就是 只會被渲染二次,所以檢視中的效果就是最後一行中的文字框資料被刪除,第一行的按鈕被刪除。

這樣的執行結果顯示不合理,怎麼解決這個問題呢,那就是新增 key 屬性。引用官方文件的話:

為了給 Vue 一個提示,以便它能跟蹤每個節點的身份,從而重用和重新排序現有元素,你需要為每項提供一個唯一 key attribute

也就是說我們需要提供一個 key 屬性,告訴 Vue 每個節點的差異,以便能夠更好的跟蹤節點資訊

<key-test v-for="(item, index) in list" :key="item">  <button @click="remove(index)">刪除{{item}}button>key-test>

使用 v-for 實現列表渲染時,動態繫結 key 屬性值,效果如下:

20d00117df3bb56b4a5a63e8cf684e51.gif

新增 key 後的效果就正常了,來分析一下原因。

這裡使用 list 陣列中的元素值作為 key 屬性值,點選三次“新增”按鈕後,list 陣列值為 [1, 2, 3]。點選第一行的“刪除1”按鈕,list 陣列中將第一個元素刪除,變為 [2, 3],重新渲染時,發現 key=2key=3 的節點沒有發生變化,而 key=1 的節點被刪除了,所以檢視中第一行的內容被刪除了,這符合我們的預期。

為什麼不用 index 作為 key 來使用呢?

如果使用 index 作為 key

<key-test v-for="(item, index) in list" :key="index">  <button @click="remove(index)">刪除{{item}}button>key-test>

測試效果:

f47d3940872f6b2432a22132e7ed1551.gif

和沒有新增 key 時的測試效果類似,這是為什麼呢?再分析一下原因。

仍然先點選三次“新增”按鈕,list 陣列中元素為 [1, 2, 3],下標分別為 0, 1, 2,點選第一行的刪除按鈕,list 陣列元素變為 [2, 3],但陣列中下標會自動重新編號,下標變為 0, 1,利用 v-for 重新渲染時,使用 index 作為 key 值,所以 key=0key=1 的元素還在,而 key=2 的元素被刪除了,檢視渲染的效果如上圖所示,仍是最後一行文字框被刪除,顯然這又是不符合正常處理邏輯的。

因此,建議儘可能在使用 v-for 時為每項提供唯一的 key 屬性,並且不使用 index 作為 key 值。