Vue中Key唯一標(biāo)識(shí)作用小結(jié)
前言
在開發(fā) Vue 列表渲染時(shí),編輯器總是提醒我們“必須綁定 key”。很多人習(xí)慣性地填入 index。但你是否思考過:key 到底在底層起到了什么作用?為什么不合理的 key 會(huì)導(dǎo)致組件狀態(tài)錯(cuò)亂甚至性能崩潰?
一、 :key 的核心作用:虛擬 DOM 的“導(dǎo)航儀”
在 Vue 更新 DOM 時(shí),其核心算法是 Diff 算法。key 的主要作用是更高效地更新虛擬 DOM。
1. 節(jié)點(diǎn)復(fù)用的關(guān)鍵
Vue 會(huì)通過判斷兩個(gè)節(jié)點(diǎn)是否為“相同節(jié)點(diǎn)”,從而決定是銷毀重建還是原地復(fù)用。 判斷相同節(jié)點(diǎn)的必要條件包括:
- 元素類型與Key 值 :Vue判斷兩個(gè)節(jié)點(diǎn)是否相同時(shí),主要判斷兩者的key和元素類型是否相等,因此如果不設(shè)置key且元素類型相同的話,它的值就是undefined(而undefined恒等于undefined),則vue可能永遠(yuǎn)認(rèn)為這是兩個(gè)相同節(jié)點(diǎn),只能去做更新操作,從而嘗試“原地復(fù)用”它們。
提示:虛擬Dom與diff算法會(huì)在后續(xù)單獨(dú)講解
二、 為什么要綁定 Key?
1. 不帶 key(原地復(fù)用策略)
當(dāng)列表順序被打亂時(shí),Vue 不會(huì)移動(dòng) DOM 元素來匹配列表項(xiàng)的順序,而是就地更新每個(gè)元素。
- 弊端:如果列表項(xiàng)包含有狀態(tài)的子組件或受控輸入框(如
<input>),原本屬于 A 項(xiàng)的輸入框內(nèi)容會(huì)“殘留”在 B 項(xiàng)的位置上,造成 UI 錯(cuò)亂。 - 性能:導(dǎo)致頻繁的屬性更新和 DOM 操作,效率低下。
2. 帶有 key(精準(zhǔn)匹配策略)
有了 key 作為唯一標(biāo)識(shí),Vue 能根據(jù) key 精準(zhǔn)找到舊節(jié)點(diǎn)樹中對(duì)應(yīng)的節(jié)點(diǎn)。
- 優(yōu)勢(shì):Vue 會(huì)移動(dòng)元素而非重新渲染,極大減少了不必要的 DOM 操作,顯著提升性能。
三、為什么不推薦使用 Index 作為 Key?
這使用 index 在進(jìn)行增刪、排序操作時(shí),如果在列表頭部添加一個(gè)新子項(xiàng)時(shí),原列表所有的子項(xiàng)index都會(huì)+1,這會(huì)讓vue認(rèn)為列表全改變了,需要全部重新生成,從而造成性能損耗。
示例:
<script setup lang="ts">
import { ref } from 'vue'
interface User {
id: number;
name: string;
}
const users = ref<User[]>([
{ id: 1, name: '張三' },
{ id: 2, name: '李四' }
])
const insertUser = () => {
// 在頭部插入一條數(shù)據(jù)
users.value.unshift({ id: Date.now(), name: '新同學(xué)' })
}
</script>
<template>
<div>
<button @click="insertUser">頭部插入數(shù)據(jù)</button>
<ul>
<li v-for="(item, index) in users" :key="index">
{{ item.name }} <input type="text" placeholder="輸入評(píng)價(jià)" />
</li>
<hr />
<li v-for="item in users" :key="item.id">
{{ item.name }} <input type="text" placeholder="輸入評(píng)價(jià)" />
</li>
</ul>
</div>
</template>
四、 總結(jié)
- 唯一性:
key必須在當(dāng)前循環(huán)層級(jí)中是唯一的,不能重復(fù)。 - 穩(wěn)定性:不要使用
Math.random()作為key,否則每次渲染都會(huì)強(qiáng)制銷毀重建所有節(jié)點(diǎn),性能極其低效。 - undefined 陷阱:如果不設(shè)置
key,它的值就是undefined。在 Diff 對(duì)比時(shí),Vue 會(huì)認(rèn)為兩個(gè)undefined節(jié)點(diǎn)是“相同”的,這正是導(dǎo)致頻繁更新、影響性能的根源。
到此這篇關(guān)于Vue中Key唯一標(biāo)識(shí)作用小結(jié)的文章就介紹到這了,更多相關(guān)Vue Key唯一標(biāo)識(shí)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
element-ui如何取消el-table的hover狀態(tài)(取消高亮顯示)
在一個(gè)項(xiàng)目中需要對(duì)element-ui的table組件進(jìn)行一些樣式的修改,其中就包括對(duì)hover效果的處理,下面這篇文章主要給大家介紹了關(guān)于element-ui如何取消el-table的hover狀態(tài)(取消高亮顯示)的相關(guān)資料,需要的朋友可以參考下2022-11-11
Vant的安裝和配合引入Vue.js項(xiàng)目里的方法步驟
這篇文章主要介紹了Vant的安裝和配合引入Vue.js項(xiàng)目里的方法步驟,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-12-12
vue引入新版 vue-awesome-swiper插件填坑問題
這篇文章主要介紹了vue引入新版 vue-awesome-swiper插件填坑問題,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-01-01
vue3中關(guān)于i18n字符串轉(zhuǎn)義問題
這篇文章主要介紹了vue3中關(guān)于i18n字符串轉(zhuǎn)義問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04
vue.js單頁面應(yīng)用實(shí)例的簡(jiǎn)單實(shí)現(xiàn)
本篇文章主要介紹了vue.js單頁面應(yīng)用實(shí)例的簡(jiǎn)單實(shí)現(xiàn),使用單頁應(yīng)用,沒有頁面切換,就沒有白屏阻塞,可以大大提高 H5 的性能,達(dá)到接近原生的流暢體驗(yàn)。2017-04-04
JavaScript的Vue.js庫入門學(xué)習(xí)教程
Vue的很多思想借鑒于Angular,但卻比較輕量和自由,這里我們整理了JavaScript的Vue.js庫入門學(xué)習(xí)教程,包括其架構(gòu)思想與核心的數(shù)據(jù)綁定方式等,需要的朋友可以參考下2016-05-05

