Vue開發(fā)實(shí)例探究key的作用詳解
前言
一提到 vue 中的 key,你會(huì)想到什么?使用v-for時(shí)需要使用 key ?key 不能重復(fù)?建議不要使用 index 來(lái)做key的值?這究竟是為什么呢?就下來(lái)我們就一起來(lái)通過(guò)實(shí)例來(lái)一探究竟。
為什么不推薦使用 index 作為 key?
我們先來(lái)看兩個(gè)例子 為了能夠監(jiān)聽元素的創(chuàng)建與銷毀,我們需要將一個(gè)div元素封裝為一個(gè)組件,取名為Test
<template>
<div>
{{ Math.floor(Math.random() * 100) }}
</div>
</template>
<script>
export default {
props: ["mark"],
mounted() {
console.log("create", this.mark)
},
beforeDestroy() {
console.log("destroy", this.mark)
}
}
</script>
使用 index 作為 key
<template>
<div>
<Test v-for="(item,index) in arr" :key="index" :mark="item"></Test>
<button @click="changeArr">change</button>
</div>
</template>
<script>
import Test from './Test'
export default {
data() {
return {
arr: [1,2,3,4,5]
}
},
components: {
Test
},
methods: {
changeArr() {
this.arr = [6,7,8,9]
}
}
};
</script>

通過(guò)點(diǎn)擊按鈕改變數(shù)組我們可以發(fā)現(xiàn)因?yàn)閿?shù)組的改變有一個(gè)組件(item 為5的組件)被銷毀,但并沒(méi)有新的 Test 組件創(chuàng)建。由此我們可以得出一個(gè)結(jié)論:如果元素 key 的值未發(fā)生變化,那么該元素就不會(huì)進(jìn)行銷毀與重建。 我們?cè)賮?lái)看下另外一個(gè)例子
<template>
<div>
<Test v-for="item in arr" :key="item" :mark="item"></Test>
<button @click="changeArr">change</button>
</div>
</template>
<script>
import Test from './Test'
export default {
data() {
return {
arr: [1,2,3,4,5]
}
},
components: {
Test
},
methods: {
changeArr() {
this.arr = [5,4,3,2,6]
}
}
};
</script>
上述兩個(gè)例子的代碼區(qū)別是:綁定的 key 不同 通過(guò)點(diǎn)擊按鈕改變數(shù)組,每個(gè)元素的 key 都會(huì)發(fā)生變化,所以元素都會(huì)被銷毀,然后重新創(chuàng)建,但事實(shí)并非如此。

實(shí)驗(yàn)結(jié)果是:只有key為1的元素被銷毀,key為6的元素被創(chuàng)建 其實(shí)這也是合理的,我最初的key為2,改變之后的key為3,但是key為3這個(gè)元素之前就存在,這就意味著我可以直接使用key為3的這個(gè)元素,無(wú)需銷毀再創(chuàng)建。 所以我們之前的結(jié)論還需要進(jìn)一步的完善:如果元素 key 的值發(fā)生改變但未產(chǎn)生新的key,那么Vue就會(huì)復(fù)用之前key的那個(gè)元素。 所以為什么不推薦 index 作為 key? 雖然上述的兩個(gè)例子都會(huì)復(fù)用 key,但他們最大的區(qū)別在于,使用index作為key會(huì)產(chǎn)生一個(gè)副作用,若使用數(shù)據(jù)本身則不會(huì)產(chǎn)生副作用。 通過(guò)第一個(gè)例子我們可以發(fā)現(xiàn),即使我們的數(shù)據(jù)發(fā)生了翻天覆地的變化,但因?yàn)槲覀兪褂胕ndex作為key,所以元素不會(huì)被銷毀與重建,這就會(huì)導(dǎo)致我們?cè)?/strong>mounted、created等鉤子中做的一些操作無(wú)法生效,若這些鉤子中有依賴父組件傳來(lái)的值,那造成的影響將是致命的。 我們?cè)倏匆粋€(gè)使用 index 引起更新錯(cuò)誤的例子
<template>
<div>
<div v-for="(item, index) in arr" :key="index">
<Test></Test>
<button @click="deleteItem(index)">delete</button>
</div>
</div>
</template>
<script>
import Test from './Test'
export default {
name: 'App',
data() {
return {
arr: [1,2,3,4,5]
}
},
components: {
Test
},
methods: {
deleteItem(i) {
this.arr.splice(i, 1)
}
}
}
</script>
無(wú)論我們點(diǎn)擊哪一個(gè)數(shù)字后的刪除按鈕,刪除的都是最后一個(gè)數(shù)字。 如果使用數(shù)組的值作為 key 則不會(huì)出現(xiàn)該錯(cuò)誤
如果 key 重復(fù)會(huì)導(dǎo)致什么樣的錯(cuò)誤?
想必這個(gè)錯(cuò)大家應(yīng)該都遇見(jiàn)過(guò)Duplicate keys detected: 'xx'. This may cause an update error.那么它到底會(huì)導(dǎo)致什么樣的更新錯(cuò)誤呢?
和使用 index 作為 key 所造成的錯(cuò)誤類似,我們將上述例子的 key 更改為一個(gè)固定的值即可復(fù)現(xiàn)該錯(cuò)誤
不過(guò),在 Vue3 中并不會(huì)在控制臺(tái)中主動(dòng)拋出 key 重復(fù)的錯(cuò)誤。
使用 key 和不使用 key 有什么差別?
復(fù)用上的差別,如果使用 key,只要 key 發(fā)生變化,那么這個(gè)元素就必定會(huì)被銷毀然后重建,若沒(méi)有key,則Vue會(huì)盡可能的復(fù)用元素,以獲取性能上的提升。(這應(yīng)該就是Vue文檔中所提到的默認(rèn)行為) 我們可以使用上面的例子,通過(guò)添加和刪除key來(lái)驗(yàn)證這一結(jié)論
key的實(shí)際應(yīng)用
- 在
v-for語(yǔ)句中使用,一是為了令 Vue 能夠正確的復(fù)用元素,二是因?yàn)榫庉嬈鲿?huì)報(bào)錯(cuò)~~~~ - 利用 key 一旦更改就會(huì)銷毀重新創(chuàng)建的特性,實(shí)現(xiàn)強(qiáng)制替換元素來(lái)完整的觸發(fā)生命周期鉤子
上述結(jié)論在Vue3中也成立嗎?
成立。 已知的不同之處在于 Vue3 不會(huì)在控制臺(tái)中主動(dòng)拋出 key 重復(fù)的錯(cuò)誤。
總結(jié)
相同父元素下的子元素
使用key
- 如果元素 key 的值未發(fā)生變化,那么該元素就不會(huì)進(jìn)行銷毀與重建。
- 如果元素 key 的值發(fā)生改變但未產(chǎn)生新的key,那么Vue就會(huì)復(fù)用之前key的那個(gè)元素。
- 如果元素 key 的值為一個(gè)全新的值,那么該元素就會(huì)被銷毀與重建,如果是組件,則會(huì)觸發(fā)完整的生命周期鉤子
不使用key
盡可能的復(fù)用節(jié)點(diǎn)
以上就是Vue開發(fā)實(shí)例探究key的作用詳解的詳細(xì)內(nèi)容,更多關(guān)于Vue key作用的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Vue項(xiàng)目中數(shù)據(jù)的深度監(jiān)聽或?qū)ο髮傩缘谋O(jiān)聽實(shí)例
這篇文章主要介紹了Vue項(xiàng)目中數(shù)據(jù)的深度監(jiān)聽或?qū)ο髮傩缘谋O(jiān)聽實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07
Vue2項(xiàng)目中對(duì)百度地圖的封裝使用詳解
近期項(xiàng)目需求相關(guān)地圖限定使用百度地圖,功能比較簡(jiǎn)單,下面這篇文章主要給大家介紹了關(guān)于Vue2項(xiàng)目中對(duì)百度地圖的封裝使用的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06
vue中數(shù)據(jù)不響應(yīng)的問(wèn)題及解決
這篇文章主要介紹了vue中數(shù)據(jù)不響應(yīng)的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09
如何使用HBuilderX把vue項(xiàng)目打包成apk
這篇文章主要介紹了如何使用HBuilderX把vue項(xiàng)目打包成apk,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
vue實(shí)現(xiàn)隨機(jī)驗(yàn)證碼功能的實(shí)例代碼
這篇文章主要介紹了vue實(shí)現(xiàn)隨機(jī)驗(yàn)證碼功能的實(shí)例代碼,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-04-04
關(guān)于electron-vue打包后運(yùn)行白屏的解決方案
這篇文章主要介紹了關(guān)于electron-vue打包后運(yùn)行白屏的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10
vue-resource + json-server模擬數(shù)據(jù)的方法
本篇文章主要介紹了vue-resource + json-server模擬數(shù)據(jù)的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11

