在vue裏面,咱們經過v-for指令來渲染一個數組列表,列表項須要咱們定義一個別名,即:html
<ul id="example-1">
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
複製代碼
在上面這個例子中,items
是咱們要渲染的數組列表,item
是數組列表項的別名,固然,咱們能夠給v-for
添加第二個參數做爲當前項的索引:vue
<ul id="example-2">
<li v-for="(item, index) in items">
{{ index }} - {{ item.message }}
</li>
</ul>
複製代碼
有經驗的同窗可能會指出,上面的例子都少了一個屬性: key
,是的,官方文檔建議咱們給v-for
渲染的每個列表項指定一個key
,那麼,key
的做用是什麼呢?vue官方文檔給瞭如下的解釋:算法
當 Vue.js 用 v-for 正在更新已渲染過的元素列表時,它默認用「就地複用」策略。若是數據項的順序被改變,Vue 將不會移動 DOM 元素來匹配數據項的順序, 而是簡單複用此處每一個元素,而且確保它在特定索引下顯示已被渲染過的每一個元素。這個相似 Vue 1.x 的 track-by="$index" 。數組
這個默認的模式是高效的,可是隻適用於不依賴子組件狀態或臨時 DOM 狀態 (例如:表單輸入值) 的列表渲染輸出。bash
爲了給 Vue 一個提示,以便它能跟蹤每一個節點的身份,從而重用和從新排序現有元素,你須要爲每項提供一個惟一 key 屬性。理想的 key 值是每項都有的惟一 id。這個特殊的屬性至關於 Vue 1.x 的 track-by ,但它的工做方式相似於一個屬性,因此你須要用 v-bind 來綁定動態值 (在這裏使用簡寫):dom
<div v-for="item in items" :key="item.id">
<!-- 內容 -->
</div>
複製代碼
建議儘量在使用 v-for 時提供 key,除非遍歷輸出的 DOM 內容很是簡單,或者是刻意依賴默認行爲以獲取性能上的提高。由於它是 Vue 識別節點的一個通用機制,key 並不與 v-for 特別關聯,key 還具備其餘用途,咱們將在後面的指南中看到其餘用途。ide
這裏我舉一個簡單的例子來講明一下:性能
在一個玩具組裝車間,小A, 小B, 小C,小D以及其餘96個流水線工人一塊兒完成組裝玩具的工做,每一個人都有本身的一輛玩具在組裝,忽然,小B肚子痛跑去上廁所了,可是小B的工做還沒完成,爲了避免影響總體進度,工人都依次往前補,小C頂替了小B的工做,小D頂替了小C的工做,以此類推,這樣雖然也是有點麻煩,還好工做定期完成了。ui
這就是就地複用大概的思路,若是不採用就地複用,那麼,當小B缺席以後,流水線上的工人(包括小B以前的)都要從新排序,100我的按照工號從新排序,從新獲取本身的工做內容,這樣子工做效率就大大下降了。this
在DOM中,就地複用的是那些沒有變化的元素,例如:
<div v-for="item in items">
<input/>
{{item.message}}
</div>
複製代碼
在這段代碼中,沒有變化的元素就是input
,當咱們刪除items的某個元素時,item.message
會發生變化,所以渲染的數據發生了變化,可是已經存在dom中的input
卻會被就地複用,具體的演示效果以下:
正如咱們上面看到的那樣,咱們但願input
也被從新渲染,這個問題的解決方案vue已經在文檔中說的很清楚了,咱們須要給每個列表項加上一個惟一的key
屬性
這個問題就涉及到了虛擬DOM的diff算法了,具體原理能夠查看知乎的一篇文章
key屬性須要綁定一個惟一的值,可是在咱們的實際項目中,不必定會有這麼一個惟一的值讓咱們綁定,所以習慣性咱們會採用index
做爲key
屬性的值,這樣作就容易產生問題了...
由於index對應的value值是會變化的,例如:
list: [
{index: 0, value: 0},
{index: 1, value: 1},
{index: 2, value: 2}
]
複製代碼
當咱們執行list.splice(1, 1)
移除index = 1的項時,list數組就會變成:
list: [
{index: 0, value: 0},
{index: 1, value: 2}
]
複製代碼
由於index
是數組元素的索引,當某個元素被移除時,被移除元素後面的元素索引都會更新,也就是說index
並非惟一的,因此vue就會採用 就地複用 原則,這時若是頁面上有相似於input
這種跟value
值沒有綁定關係的元素時,這些元素將會被複用,有可能就得不到咱們要的效果了
總結: 相信用vue的人都會遇到這麼一個列表渲染元素混亂的問題,key
屬性看似簡單可是第一次遇到的時候是會很納悶的,關於列表渲染比較常見的坑還有數組和對象的監測和更新,this.$set
你值得擁有,詳情能夠查看官方文檔,本文若是有錯漏,歡迎指出~