詳解如何理解vue的key屬性
如果沒有這個(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)的模式是高效的,但是只適用于不依賴子組件狀態(tài)或臨時(shí) DOM 狀態(tài) (例如:表單輸入值) 的列表渲染輸出。
如上引用自官網(wǎng),這個(gè)模式就是上面的“就地復(fù)用”策略。那么是不是依賴子組件狀態(tài)的列表渲染采用上面的模式就出問題了呢。如下測(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>
操作如下:
問題出現(xiàn)了:發(fā)生變化時(shí),子組件 沒有更新
ps: 測(cè)試臨時(shí) DOM 狀態(tài) (例如:表單輸入值)可以參考這個(gè)鏈接 List Rendering and Vue's v-for Directive
key的作用
這個(gè)時(shí)候引入 key 就可以解決這個(gè)問題。 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 來作為 key 則兩次對(duì)比沒有區(qū)別,就會(huì)出現(xiàn)上面動(dòng)圖里出現(xiàn)的子組件沒有更新的情況。
可以通過查看下面兩個(gè)動(dòng)圖查看dom節(jié)點(diǎn)的變化。第一個(gè)gif是沒有使用 key ,第二個(gè)是使用了 key ??梢钥吹轿尹c(diǎn)了按鈕后,第一個(gè)只是更新 <p> 標(biāo)簽的內(nèi)容節(jié)點(diǎn)。第二個(gè)是移動(dòng)了某一項(xiàng)的 <li> 標(biāo)簽。

ps: 另外可以通過chrome的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)畫時(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
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
vue+elementUI中el-radio設(shè)置默認(rèn)值方式
這篇文章主要介紹了vue+elementUI中el-radio設(shè)置默認(rèn)值方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
Vue3如何自定義指令directive(如權(quán)限控制)
本文詳細(xì)介紹了如何在Vue3項(xiàng)目中創(chuàng)建自定義指令directive1,首先,在src/directives/index.ts文件中引入自定義指令,然后,創(chuàng)建src/directives/permission.ts文件來定義具體指令邏輯,在main.ts文件中引入并注冊(cè)該指令,最后,在頁(yè)面中使用自定義指令2024-12-12
vue el-switch綁定數(shù)值時(shí)需要注意的問題
在Vue中使用`el-switch`組件時(shí),綁定數(shù)值類型時(shí)應(yīng)使用布爾值(true/false),而綁定字符串類型時(shí)應(yīng)使用字符串('true'/'false')2024-12-12
基于vue-cli vue-router搭建底部導(dǎo)航欄移動(dòng)前端項(xiàng)目
這篇文章主要介紹了基于vue-cli vue-router搭建底部導(dǎo)航欄移動(dòng)前端項(xiàng)目,項(xiàng)目中主要用了Flex布局,以及viewport相關(guān)知識(shí),已達(dá)到適應(yīng)各終端屏幕的目的。需要的朋友可以參考下2018-02-02
Vue關(guān)鍵字搜索功能實(shí)戰(zhàn)小案例
在vue項(xiàng)目中,搜索功能是我們經(jīng)常需要使用的一個(gè)場(chǎng)景,下面這篇文章主要給大家介紹了關(guān)于Vue關(guān)鍵字搜索功能的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06
Vue解析剪切板圖片并實(shí)現(xiàn)發(fā)送功能
這篇文章主要介紹了Vue解析剪切板圖片并實(shí)現(xiàn)發(fā)送功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02
vue項(xiàng)目移動(dòng)端實(shí)現(xiàn)ip輸入框問題
這篇文章主要介紹了vue項(xiàng)目移動(dòng)端實(shí)現(xiàn)ip輸入框問題,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-03-03

