国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > JavaScript > 正文

詳解key在Vue列表渲染時究竟起到了什么作用

2024-05-06 15:40:20
字體:
供稿:網(wǎng)友

Vue2+采用diff算法來進(jìn)行新舊vnode的對比從而更新DOM節(jié)點(diǎn)。而通常在我們使用v-for這個指令的時候,Vue會要求你給循環(huán)列表的每一項添加唯一的key,那么這個key在渲染列表時究竟起到了什么作用呢?

在解釋這一點(diǎn)之前,你最好已經(jīng)了解Vue的diff算法的具體原理是什么。

Vue2更新真實(shí)DOM的操作主要是兩種:創(chuàng)建新DOM節(jié)點(diǎn)并移除舊DOM節(jié)點(diǎn)和更新已存在的DOM節(jié)點(diǎn),這兩種方式里創(chuàng)建新DOM節(jié)點(diǎn)的開銷肯定是遠(yuǎn)大于更新或移動已有的DOM節(jié)點(diǎn),所以在diff中邏輯都是為了減少新的創(chuàng)建而更多的去復(fù)用已有DOM節(jié)點(diǎn)來完成DOM的更新。

在新舊vnode的diff過程中,key是判斷兩個節(jié)點(diǎn)是否為同一節(jié)點(diǎn)的首要條件:

// 參見Vue2源碼 core/vdom/patch.jsfunction sameVnode (a, b) {  return (    a.key === b.key && (      (        a.tag === b.tag &&        a.isComment === b.isComment &&        isDef(a.data) === isDef(b.data) &&        sameInputType(a, b)      ) || (        isTrue(a.isAsyncPlaceholder) &&        a.asyncFactory === b.asyncFactory &&        isUndef(b.asyncFactory.error)      )    )  )}

值得注意的是,如果新舊vnode的key值都未定義的話那么兩個key都為undefined,a.key === b.key 是成立的

接下來是在updateChildren方法中,這個方法會對新舊vnode進(jìn)行diff,然后將比對出的結(jié)果用來更新真實(shí)的DOM

// 參見Vue2源碼 core/vdom/patch.jsfunction updateChildren (parentElm, oldCh, newCh, insertedVnodeQueue, removeOnly) {  ...  while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {    if (isUndef(oldStartVnode)) {      ...    } else if (isUndef(oldEndVnode)) {      ...    } else if (sameVnode(oldStartVnode, newStartVnode)) {      ...    } else if (sameVnode(oldEndVnode, newEndVnode)) {      ...    } else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right      ...    } else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left      ...    } else {      if (isUndef(oldKeyToIdx)) oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx)      idxInOld = isDef(newStartVnode.key)        ? oldKeyToIdx[newStartVnode.key]        : findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx)      if (isUndef(idxInOld)) { // New element        createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx)      } else {        vnodeToMove = oldCh[idxInOld]        if (sameVnode(vnodeToMove, newStartVnode)) {          patchVnode(vnodeToMove, newStartVnode, insertedVnodeQueue, newCh, newStartIdx)          oldCh[idxInOld] = undefined          canMove && nodeOps.insertBefore(parentElm, vnodeToMove.elm, oldStartVnode.elm)        } else {          // same key but different element. treat as new element          createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm, false, newCh, newStartIdx)        }      }      newStartVnode = newCh[++newStartIdx]    }  }  ...}            
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 登封市| 黄山市| 西畴县| 光泽县| 玉门市| 关岭| 满城县| 揭阳市| 高州市| 乌海市| 祁连县| 西丰县| 云安县| 长寿区| 龙陵县| 安龙县| 宝兴县| 灵石县| 明星| 旺苍县| 霍林郭勒市| 囊谦县| 樟树市| 台湾省| 阳西县| 深圳市| 大渡口区| 辽阳市| 怀远县| 南川市| 桐梓县| 贵南县| 大埔县| 玉溪市| 惠水县| 巴南区| 静乐县| 县级市| 滦南县| 巩义市| 从化市|