// 没有key的情况, 节点位置不变,但是节点innerText内容更新了 [ '<div>4</div>', // id: A '<div>1</div>', // id: B '<div>3</div>', // id: C '<div>5</div>', // id: D '<div>2</div>' // id: E ]
// 有key的情况,dom节点位置进行了交换,但是内容没有更新 // <div v-for="i in dataList" :key='i'>{{ i }}</div> [ '<div>4</div>', // id: D '<div>1</div>', // id: A '<div>3</div>', // id: C '<div>5</div>', // id: E '<div>2</div>' // id: B ]
// 1. 没有key的情况, 节点位置不变,内容也更新了 [ '<div>3</div>', // id: A '<div>4</div>', // id: B '<div>5</div>', // id: C '<div>6</div>', // id: D '<div>7</div>' // id: E ]
// 2. 有key的情况, 节点删除了 A, B 节点,新增了 F, G 节点 // <div v-for="i in dataList" :key='i'>{{ i }}</div> [ '<div>3</div>', // id: C '<div>4</div>', // id: D '<div>5</div>', // id: E '<div>6</div>', // id: F '<div>7</div>' // id: G ]
function createKeyToOldIdx (children, beginIdx, endIdx) { let i, key const map = {} for (i = beginIdx; i <= endIdx; ++i) { key = children[i].key if (isDef(key)) map[key] = i } return map }
遍历寻找
1 2 3 4 5 6 7 8
// sameVnode 是对比新旧节点是否相同的函数 function findIdxInOld (node, oldCh, start, end) { for (let i = start; i < end; i++) { const c = oldCh[i] if (isDef(c) && sameVnode(node, c)) return i } }