Vue開發(fā)實例探究key的作用詳解
前言
一提到 vue 中的 key,你會想到什么?使用v-for
時需要使用 key ?key 不能重復?建議不要使用 index 來做key的值?這究竟是為什么呢?就下來我們就一起來通過實例來一探究竟。
為什么不推薦使用 index 作為 key?
我們先來看兩個例子 為了能夠監(jiān)聽元素的創(chuàng)建與銷毀,我們需要將一個div
元素封裝為一個組件,取名為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>
通過點擊按鈕改變數(shù)組我們可以發(fā)現(xiàn)因為數(shù)組的改變有一個組件(item 為5的組件)被銷毀,但并沒有新的 Test 組件創(chuàng)建。由此我們可以得出一個結(jié)論:如果元素 key 的值未發(fā)生變化,那么該元素就不會進行銷毀與重建。 我們再來看下另外一個例子
<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>
上述兩個例子的代碼區(qū)別是:綁定的 key 不同 通過點擊按鈕改變數(shù)組,每個元素的 key 都會發(fā)生變化,所以元素都會被銷毀,然后重新創(chuàng)建,但事實并非如此。
實驗結(jié)果是:只有key為1的元素被銷毀,key為6的元素被創(chuàng)建 其實這也是合理的,我最初的key為2,改變之后的key為3,但是key為3這個元素之前就存在,這就意味著我可以直接使用key為3的這個元素,無需銷毀再創(chuàng)建。 所以我們之前的結(jié)論還需要進一步的完善:如果元素 key 的值發(fā)生改變但未產(chǎn)生新的key,那么Vue就會復用之前key的那個元素。 所以為什么不推薦 index 作為 key? 雖然上述的兩個例子都會復用 key,但他們最大的區(qū)別在于,使用index作為key會產(chǎn)生一個副作用,若使用數(shù)據(jù)本身則不會產(chǎn)生副作用。 通過第一個例子我們可以發(fā)現(xiàn),即使我們的數(shù)據(jù)發(fā)生了翻天覆地的變化,但因為我們使用index作為key,所以元素不會被銷毀與重建,這就會導致我們在mounted、created
等鉤子中做的一些操作無法生效,若這些鉤子中有依賴父組件傳來的值,那造成的影響將是致命的。 我們再看一個使用 index 引起更新錯誤的例子
<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>
無論我們點擊哪一個數(shù)字后的刪除按鈕,刪除的都是最后一個數(shù)字。 如果使用數(shù)組的值作為 key 則不會出現(xiàn)該錯誤
如果 key 重復會導致什么樣的錯誤?
想必這個錯大家應該都遇見過Duplicate keys detected: 'xx'. This may cause an update error.
那么它到底會導致什么樣的更新錯誤呢?
和使用 index 作為 key 所造成的錯誤類似,我們將上述例子的 key 更改為一個固定的值即可復現(xiàn)該錯誤
不過,在 Vue3 中并不會在控制臺中主動拋出 key 重復的錯誤。
使用 key 和不使用 key 有什么差別?
復用上的差別,如果使用 key,只要 key 發(fā)生變化,那么這個元素就必定會被銷毀然后重建,若沒有key,則Vue會盡可能的復用元素,以獲取性能上的提升。(這應該就是Vue文檔中所提到的默認行為) 我們可以使用上面的例子,通過添加和刪除key來驗證這一結(jié)論
key的實際應用
- 在
v-for
語句中使用,一是為了令 Vue 能夠正確的復用元素,二是因為編輯器會報錯~~~~ - 利用 key 一旦更改就會銷毀重新創(chuàng)建的特性,實現(xiàn)強制替換元素來完整的觸發(fā)生命周期鉤子
上述結(jié)論在Vue3中也成立嗎?
成立。 已知的不同之處在于 Vue3 不會在控制臺中主動拋出 key 重復的錯誤。
總結(jié)
相同父元素下的子元素
使用key
- 如果元素 key 的值未發(fā)生變化,那么該元素就不會進行銷毀與重建。
- 如果元素 key 的值發(fā)生改變但未產(chǎn)生新的key,那么Vue就會復用之前key的那個元素。
- 如果元素 key 的值為一個全新的值,那么該元素就會被銷毀與重建,如果是組件,則會觸發(fā)完整的生命周期鉤子
不使用key
盡可能的復用節(jié)點
以上就是Vue開發(fā)實例探究key的作用詳解的詳細內(nèi)容,更多關(guān)于Vue key作用的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue如何使用pdf.js實現(xiàn)在線查看pdf文件功能
PDF.js是一個開源的JavaScript庫,用于在網(wǎng)頁上渲染和顯示PDF文件,在Vue中使用PDF.js來預覽PDF文件是很常見的需求,這篇文章主要給大家介紹了關(guān)于vue如何使用pdf.js實現(xiàn)在線查看pdf文件功能的相關(guān)資料,需要的朋友可以參考下2024-03-03Vue執(zhí)行方法,方法獲取data值,設(shè)置data值,方法傳值操作
這篇文章主要介紹了Vue執(zhí)行方法,方法獲取data值,設(shè)置data值,方法傳值操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08vue-cli 目錄結(jié)構(gòu)詳細講解總結(jié)
這篇文章主要介紹了vue-cli 目錄結(jié)構(gòu)詳細講解總結(jié),詳細的介紹了整個項目的目錄以及目錄文件的用法,非常具有實用價值,需要的朋友可以參考下2019-01-01解決vue項目中頁面調(diào)用數(shù)據(jù) 在數(shù)據(jù)加載完畢之前出現(xiàn)undefined問題
今天小編就為大家分享一篇解決vue項目中頁面調(diào)用數(shù)據(jù) 在數(shù)據(jù)加載完畢之前出現(xiàn)undefined問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11