Vue中Key唯一標(biāo)識作用小結(jié)
前言
在開發(fā) Vue 列表渲染時(shí),編輯器總是提醒我們“必須綁定 key”。很多人習(xí)慣性地填入 index。但你是否思考過:key 到底在底層起到了什么作用?為什么不合理的 key 會導(dǎo)致組件狀態(tài)錯(cuò)亂甚至性能崩潰?
一、 :key 的核心作用:虛擬 DOM 的“導(dǎo)航儀”
在 Vue 更新 DOM 時(shí),其核心算法是 Diff 算法。key 的主要作用是更高效地更新虛擬 DOM。
1. 節(jié)點(diǎn)復(fù)用的關(guān)鍵
Vue 會通過判斷兩個(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算法會在后續(xù)單獨(dú)講解
二、 為什么要綁定 Key?
1. 不帶 key(原地復(fù)用策略)
當(dāng)列表順序被打亂時(shí),Vue 不會移動 DOM 元素來匹配列表項(xiàng)的順序,而是就地更新每個(gè)元素。
- 弊端:如果列表項(xiàng)包含有狀態(tài)的子組件或受控輸入框(如
<input>),原本屬于 A 項(xiàng)的輸入框內(nèi)容會“殘留”在 B 項(xiàng)的位置上,造成 UI 錯(cuò)亂。 - 性能:導(dǎo)致頻繁的屬性更新和 DOM 操作,效率低下。
2. 帶有 key(精準(zhǔn)匹配策略)
有了 key 作為唯一標(biāo)識,Vue 能根據(jù) key 精準(zhǔn)找到舊節(jié)點(diǎn)樹中對應(yīng)的節(jié)點(diǎn)。
- 優(yōu)勢:Vue 會移動元素而非重新渲染,極大減少了不必要的 DOM 操作,顯著提升性能。
三、為什么不推薦使用 Index 作為 Key?
這使用 index 在進(jìn)行增刪、排序操作時(shí),如果在列表頭部添加一個(gè)新子項(xiàng)時(shí),原列表所有的子項(xiàng)index都會+1,這會讓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="輸入評價(jià)" />
</li>
<hr />
<li v-for="item in users" :key="item.id">
{{ item.name }} <input type="text" placeholder="輸入評價(jià)" />
</li>
</ul>
</div>
</template>
四、 總結(jié)
- 唯一性:
key必須在當(dāng)前循環(huán)層級中是唯一的,不能重復(fù)。 - 穩(wěn)定性:不要使用
Math.random()作為key,否則每次渲染都會強(qiáng)制銷毀重建所有節(jié)點(diǎn),性能極其低效。 - undefined 陷阱:如果不設(shè)置
key,它的值就是undefined。在 Diff 對比時(shí),Vue 會認(rèn)為兩個(gè)undefined節(jié)點(diǎn)是“相同”的,這正是導(dǎo)致頻繁更新、影響性能的根源。
到此這篇關(guān)于Vue中Key唯一標(biāo)識作用小結(jié)的文章就介紹到這了,更多相關(guān)Vue Key唯一標(biāo)識內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue 2.0學(xué)習(xí)筆記之Vue中的computed屬性
本篇文章主要介紹了Vue 2.0學(xué)習(xí)筆記之Vue中的computed屬性,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10
vue.js集成echarts時(shí)遇到的一些問題總結(jié)
這篇文章主要給大家總結(jié)介紹了關(guān)于vue.js集成echarts遇到的一些問題,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
vue forEach循環(huán)數(shù)組拿到自己想要的數(shù)據(jù)方法
今天小編就為大家分享一篇vue forEach循環(huán)數(shù)組拿到自己想要的數(shù)據(jù)方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09
公共Hooks封裝報(bào)表導(dǎo)出useExportExcel實(shí)現(xiàn)詳解
這篇文章主要為大家介紹了公共Hooks封裝報(bào)表導(dǎo)出useExportExcel實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
如何解決sass-loader和node-sass版本沖突的問題
這篇文章主要介紹了如何解決sass-loader和node-sass版本沖突的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04

