最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

【實(shí)戰(zhàn)】為什么使用v-for時必須添加唯一的key?

2020-06-24 14:51 作者:校招VIP  | 我要投稿

01-v-for中的key


使用v-for更新已渲染的元素列表時,默認(rèn)用就地復(fù)用策略;


列表數(shù)據(jù)修改的時候,他會根據(jù)key值去判斷某個值是否修改,如果修改,則重新渲染這一項(xiàng),否則復(fù)用之前的元素;


我們在使用的使用經(jīng)常會使用index(即數(shù)組的下標(biāo))來作為key,但其實(shí)這是不推薦的一種使用方法;


舉個例子

const list = [
? ?{
? ? ? ?id: 1,
? ? ? ?name: 'test1',
? ?},
? ?{
? ? ? ?id: 2,
? ? ? ?name: 'test2',
? ?},
? ?{
? ? ? ?id: 3,
? ? ? ?name: 'test3',
? ?},
]
<div v-for="(item, index) in list"?:key="index"?>{{item.name}}</div>


上面這種是我們做項(xiàng)目中常用到的一種場景,因?yàn)椴患觡ey,vue現(xiàn)在直接報(bào)錯,


所以我使用index作為key;下面列舉兩種常見的數(shù)據(jù)更新情況。


02-在最后一條數(shù)據(jù)后再加一條數(shù)據(jù)


const list = [
? ?{
? ? ? ?id: 1,
? ? ? ?name: 'test1',
? ?},
? ?{
? ? ? ?id: 2,
? ? ? ?name: 'test2',
? ?},
? ?{
? ? ? ?id: 3,
? ? ? ?name: 'test3',
? ?},
? ?{
? ? ? ?id: 4,
? ? ? ?name: '我是在最后添加的一條數(shù)據(jù)',
? ?},
]

此時前三條數(shù)據(jù)直接復(fù)用之前的,新渲染最后一條數(shù)據(jù),此時用index作為key,沒有任何問題;


03-在中間插入一條數(shù)據(jù)


const list = [
? ?{
? ? ? ?id: 1,
? ? ? ?name: 'test1',
? ?},
? ?{
? ? ? ?id: 4,
? ? ? ?name: '我是插隊(duì)的那條數(shù)據(jù)',
? ?}
? ?{
? ? ? ?id: 2,
? ? ? ?name: 'test2',
? ?},
? ?{
? ? ? ?id: 3,
? ? ? ?name: 'test3',
? ?},
]

此時更新渲染數(shù)據(jù),通過index定義的key去進(jìn)行前后數(shù)據(jù)的對比,發(fā)現(xiàn)

之前的數(shù)據(jù) ? ? ? ? ? ? ? ? ? ? ? ? 之后的數(shù)據(jù)

key: 0 ?index: 0 name: test1 ? ? key: 0 ?index: 0 name: test1
key: 1 ?index: 1 name: test2 ? ? key: 1 ?index: 1 name: 我是插隊(duì)的那條數(shù)據(jù)
key: 2 ?index: 2 name: test3 ? ? key: 2 ?index: 2 name: test2
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?key: 3 ?index: 3 name: test3

通過上面清晰的對比,發(fā)現(xiàn)除了第一個數(shù)據(jù)可以復(fù)用之前的之外,另外三條數(shù)據(jù)都需要重新渲染;


是不是很驚奇,我明明只是插入了一條數(shù)據(jù),怎么三條數(shù)據(jù)都要重新渲染?


而我想要的只是新增的那一條數(shù)據(jù)新渲染出來就行了


最好的辦法是使用數(shù)組中不會變化的那一項(xiàng)作為key值,對應(yīng)到項(xiàng)目中,


即每條數(shù)據(jù)都有一個唯一的id,來標(biāo)識這條數(shù)據(jù)的唯一性;使用id作為key值,


我們再來對比一下向中間插入一條數(shù)據(jù),此時會怎么去渲染

之前的數(shù)據(jù) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 之后的數(shù)據(jù)

key: 1 ?id: 1 index: 0 name: test1 ? ? key: 1 ?id: 1 index: 0 ?name: test1
key: 2 ?id: 2 index: 1 name: test2 ? ? key: 4 ?id: 4 index: 1 ?name: 我是插隊(duì)的那條數(shù)據(jù)
key: 3 ?id: 3 index: 2 name: test3 ? ? key: 2 ?id: 2 index: 2 ?name: test2
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?key: 3 ?id: 3 index: 3 ?name: test3

現(xiàn)在對比發(fā)現(xiàn)只有一條數(shù)據(jù)變化了,就是id為4的那條數(shù)據(jù),因此只要新渲染這一條數(shù)據(jù)就可以了,其他都是就復(fù)用之前的;


同理在react中使用map渲染列表時,也是必須加key,且推薦做法也是使用id,也是這個原因;


其實(shí),真正的原因并不是vue和react怎么怎么,而是因?yàn)閂irtual DOM 使用Diff算法實(shí)現(xiàn)的原因,


下面大致從虛擬DOM的Diff算法實(shí)現(xiàn)的角度去解釋一下


vue和react的虛擬DOM的Diff算法大致相同,其核心是基于兩個簡單的假設(shè):
1、兩個相同的組件產(chǎn)生類似的DOM結(jié)構(gòu),不同的組件產(chǎn)生不同的DOM結(jié)構(gòu)。
2、同一層級的一組節(jié)點(diǎn),他們可以通過唯一的id進(jìn)行區(qū)分。


基于以上這兩點(diǎn)假設(shè),使得虛擬DOM的Diff算法的復(fù)雜度從O(n^3)降到了O(n)。


引用React’s diff algorithm中的例子:



當(dāng)某一層有很多相同的節(jié)點(diǎn)時,也就是列表節(jié)點(diǎn)時,Diff算法的更新過程默認(rèn)情況下也是遵循以上原則。比如一下這個情況:

我們希望可以在B和C之間加一個F,Diff算法默認(rèn)執(zhí)行起來是這樣的:


即把C更新成F,D更新成C,E更新成D,最后再插入E,是不是很沒有效率?


所以我們需要使用key來給每個節(jié)點(diǎn)做一個唯一標(biāo)識,Diff算法就可以正確的識別此節(jié)點(diǎn),找到正確的位置區(qū)插入新的節(jié)點(diǎn)。



所以一句話,key的作用主要是為了高效的更新虛擬DOM。另外vue中在使用相同標(biāo)簽名元素的過渡切換時,也會使用到key屬性,


其目的也是為了讓vue可以區(qū)分它們,否則vue只會替換其內(nèi)部屬性而不會觸發(fā)過渡效果。

今日學(xué)習(xí)
原360教育CTO小班親授

校招Offer月薪6000~10000+

心動了就查看下方課程詳細(xì)了解吧


【實(shí)戰(zhàn)】為什么使用v-for時必須添加唯一的key?的評論 (共 條)

分享到微博請遵守國家法律
阳高县| 宁陕县| 全椒县| 嘉定区| 内丘县| 青冈县| 崇信县| 葫芦岛市| 三江| 阳谷县| 大同县| 冷水江市| 丰顺县| 泊头市| 苏尼特左旗| 集安市| 铜山县| 盐边县| 长沙市| 彩票| 红河县| 重庆市| 黄大仙区| 白河县| 和硕县| 台南市| 雷州市| 左权县| 正宁县| 墨脱县| 梅河口市| 黑山县| 柏乡县| 湖北省| 东乡族自治县| 双流县| 那曲县| 望谟县| 苏尼特左旗| 称多县| 赤城县|