我们为什么要在vue中使用key
最新地址:https://juejin.cn/post/7402204174945353755
案例如下
<template>
<div>
<ul>
<li
v-for="(item, index) in listData"
>
<input type="text">
<button @click="deleteProperty(index)">删除</button>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'key',
data() {
return {
listData: [
{
id: 11,
value: 1
},
{
id: 22,
value: 2
},
{
id: 33,
value: 3
},
{
id: 44,
value: 4
},
{
id: 55,
value: 5
}
]
}
},
methods: {
deleteProperty(index) {
this.listData.splice(index, 1);
}
}
}
</script>
代码执行完毕后,我们可以看到以下的demo,此时我们点击下图所示的删除按钮,然后观看结果
点击前
点击后
原因
在vue里的diff算法中有一个判断节点是否相同的逻辑
其中,sel是节点的标签名,key就是节点所绑定的key,当节点没有key的时候,这时的key默认是undefined,如果前后变更的节点都没有key存在且元素标签名相同时,就判断这两个节点是相同的。
那么此时我们就可以查看diff过程了
1、2节点是没有变化的,所以保持原样。我们来看旧节点的第3节点和第4节点的对比,首先根据上面diff算法中判断节点是否相同的逻辑来看,这两者的共同点为:
1:sel为li
2:key为undefined
所以这两个节点满足节点相同的条件。
此时我们就要进行对比里面的子节点,子节点的相同点为
1:sel为input
2:key为undefined
此时这两个子节点也满足节点相同的条件。
那么也就是说这两个节点都是完全一样的,在diff中的处理就是元素复用,不进行任何修改,也保持原样。
其中第4节点和第5节点的比较也是同理保持原本的元素不变。由于我们删除了一个元素,所以旧节点直接舍弃掉了第5个元素。才有了操作后的结果。
综上所述,使用v-for循环时,最好把key值加上且最好不要使用index作为循环的key。否则容易出现diff错误的情况。
使用key
<li
v-for="(item, index) in listData"
:key="item.id"
>
<input type="text">
<button @click="deleteProperty(index)">删除</button>
</li>
然后发现结果就正常了
diff过程
使用了key绑定后,新旧元素都能各自匹配上自己能匹配的元素。匹配完毕后发现3是多余的,故能正常删除3元素。
注意:这里如果使用index作为key值的话也是不能达到预期效果的,因为对应的key值为
旧节点的key | 新节点的key |
---|---|
0 | 0 |
1 | 1 |
2 | 2 |
3 | 3 |
4 | - |
然后发现对比过程就像没写key的对比过程一样了,所以这也是使用index当key的坏处了。 |
当然了,如果表格数据不涉及更改的话,可以使用index当key。