若是沒有這個屬性的時候vue應用 in-place patch(就地複用)策略。列表裏的順序發生改變的時候好比shuffle(列表打亂)的時候,vue爲了提高性能,不會移動dom元素,只是更新相應元素的內容節點。javascript
這個默認的模式是高效的,可是隻適用於不依賴子組件狀態或臨時 DOM 狀態 (例如:表單輸入值) 的列表渲染輸出。css
如上引用自官網,這個模式就是上面的「就地複用」策略。那麼是否是依賴子組件狀態的列表渲染採用上面的模式就出問題了呢。以下測試代碼:html
<ul>
<li v-for="item in items">
<p>{{ item.title }}</p>
<p>{{ item.des }}</p>
<tweet-component></tweet-component>
</li>
</ul>
<script> Vue.component("tweet-component", { template: ` <div class="tweet"> <div class="box"> {{xixi}} </div> </div> `, data() { return { xixi: Math.random() }; } }); new Vue({ el: "#app", data: { items: [ { title: "nihao1", des: "xiexie1" }, { title: "nihao2", des: "xiexie2" }, { title: "nihao3", des: "xiexie3" } ] }, methods: { shuffle() { // lodash的shuffle方法 this.items = _.shuffle(this.items); } } }); </script>
複製代碼
操做以下: vue
問題出現了:發生變化時,子組件 沒有更新。ps: 測試臨時 DOM 狀態 (例如:表單輸入值)能夠參考這個連接 List Rendering and Vue’s v-for Directivejava
這個時候引入 key
就能夠解決這個問題。key
的做用是給予一個節點惟一的身份識別,有相同父元素的子元素必須有獨特的 key
。這樣它能夠先後對比,算出哪些節點是要重複使用或者調整順序。好比原先的 key
的順序是i1,i2,i3
,以後變成了i2,i1,i3
這個時候只要i3保持不變,把i2insertBefore
到i1節點前就好了(以上是舉例,vue具體怎麼操做的須要去研究源碼)。若是是利用數組的index
來做爲 key
則兩次對比沒有區別,就會出現上面動圖裏出現的子組件沒有更新的狀況。web
能夠經過查看下面兩個動圖查看dom節點的變化。第一個gif是沒有使用 key
,第二個是使用了 key
。能夠看到我點了按鈕後,第一個只是更新<p>
標籤的內容節點。第二個是移動了某一項的<li>
標籤。chrome
ps: 另外能夠經過chrome的dom斷點功能查看子元素的插入刪除。api
DOM 更改斷點數組
key不是隻能用在v-for上還能夠用在其餘元素上。以下代碼app
<div v-if="toggle">Hello</div>
<div v-else>Goodbye</div>
複製代碼
切換toggle時,它也是切換div。若是你想用上enter/leave animations時,即節點插入和刪除的時候的動畫時就要打破這個複用,以下:
<transition>
<div v-if="toggle" key="1">Hello</div>
<div v-else key="2">Goodbye</div>
</transition>
複製代碼
若是你的列表不發生變化,或者你只是往列表最後一項添加元素則看似沒必要要增長key
字段。可是你的項目中有不少列表的時候,你有的須要加key
,有的不須要加。還不如全部的都加上呢避免別人理解困難(^._.^)ノ。