您好,登錄后才能下訂單哦!
如果沒(méi)有這個(gè)屬性的時(shí)候vue應(yīng)用 in-place patch(就地復(fù)用)策略。列表里的順序發(fā)生改變的時(shí)候比如shuffle(列表打亂)的時(shí)候,vue為了提升性能,不會(huì)移動(dòng)dom元素,只是更新相應(yīng)元素的內(nèi)容節(jié)點(diǎn)。
就地復(fù)用的弊端
這個(gè)默認(rèn)的模式是高效的,但是只適用于不依賴(lài)子組件狀態(tài)或臨時(shí) DOM 狀態(tài) (例如:表單輸入值) 的列表渲染輸出。
如上引用自官網(wǎng),這個(gè)模式就是上面的“就地復(fù)用”策略。那么是不是依賴(lài)子組件狀態(tài)的列表渲染采用上面的模式就出問(wèn)題了呢。如下測(cè)試代碼:
<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>
操作如下:
問(wèn)題出現(xiàn)了:發(fā)生變化時(shí),子組件 沒(méi)有更新
ps: 測(cè)試臨時(shí) DOM 狀態(tài) (例如:表單輸入值)可以參考這個(gè)鏈接 List Rendering and Vue's v-for Directive
key的作用
這個(gè)時(shí)候引入 key
就可以解決這個(gè)問(wèn)題。 key
的作用是給予一個(gè)節(jié)點(diǎn)唯一的身份識(shí)別,有相同父元素的子元素必須有獨(dú)特的 key
。這樣它可以前后對(duì)比,算出哪些節(jié)點(diǎn)是要重復(fù)使用或者調(diào)整順序。比如原先的 key
的順序是 i1,i2,i3
,之后變成了 i2,i1,i3
這個(gè)時(shí)候只要i3保持不變,把i2 insertBefore
到i1節(jié)點(diǎn)前就行了(以上是舉例,vue具體怎么操作的需要去研究源碼)。如果是利用數(shù)組的 index
來(lái)作為 key
則兩次對(duì)比沒(méi)有區(qū)別,就會(huì)出現(xiàn)上面動(dòng)圖里出現(xiàn)的子組件沒(méi)有更新的情況。
可以通過(guò)查看下面兩個(gè)動(dòng)圖查看dom節(jié)點(diǎn)的變化。第一個(gè)gif是沒(méi)有使用 key
,第二個(gè)是使用了 key
??梢钥吹轿尹c(diǎn)了按鈕后,第一個(gè)只是更新 <p>
標(biāo)簽的內(nèi)容節(jié)點(diǎn)。第二個(gè)是移動(dòng)了某一項(xiàng)的 <li>
標(biāo)簽。
ps: 另外可以通過(guò)chrome的dom斷點(diǎn)功能查看子元素的插入刪除。
DOM 更改斷點(diǎn)
key的其他用途
key不是只能用在v-for上還可以用在其他元素上。如下代碼
<div v-if="toggle">Hello</div> <div v-else>Goodbye</div>
切換toggle時(shí),它也是切換div。如果你想用上enter/leave animations時(shí),即節(jié)點(diǎn)插入和刪除的時(shí)候的動(dòng)畫(huà)時(shí)就要打破這個(gè)復(fù)用,如下:
<transition> <div v-if="toggle" key="1">Hello</div> <div v-else key="2">Goodbye</div> </transition>
總結(jié)
如果你的列表不發(fā)生變化,或者你只是往列表最后一項(xiàng)添加元素則看似不必要增加 key
字段。但是你的項(xiàng)目中有很多列表的時(shí)候,你有的需要加 key
,有的不需要加。還不如所有的都加上呢避免別人理解困難(^._.^)ノ。
參考鏈接
https://vuejs.org/v2/guide/list.html#key
vuejs.org/v2/api/#key
https://forum.vuejs.org/t/simple-clarification-of-when-using-key-with-v-for-is-appropriate-and-why/28966/5
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。