为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。理想的 key 值是每项都有唯一 id。这个特殊的属性相当于 Vue 1.x 的 track-by ,但它的工作方式类似于一个属性,所以你需要用 v-bind 来绑定动态值(在这里使用简写):
在这里插入图片描述

先来讲一个例子:
现在假设你有三个子组件,每个子组件里面有一个「有状态的」孙子组件。
在这里插入图片描述
点击第二个,将第二个删除,将会出现什么情况?页面中会显示 序号为0 和3 吗?
不会,会出现下面的结果:
在这里插入图片描述
这和我们预期的结果不一样,为什么呢?我们明明删除了2,但是为什么最后删除的却是3呢?其实这个过程中,vue 会认为我们做了两件事:

  • 把2变成了3
  • 然后把原来的3删除了

首先对比 1 和 1,发现「1 没变」;然后对比 2 和 3,发现「2 变成了 3」;最后对比 undefined 和 3,发现「3 被删除了」。

所以计算机的结论是:「2 变成了 3」以及「3 被删除了」,有毛病吗?没毛病。

破解方法

怎么让 Vue 知道我删除的是第二个而不是第三个呢?
用 key 就好了。
我们以计算机的角度来思考一下:
原本的数组是 [{ id: 1, value: 1 }, { id: 2, value: 2 }, { id: 3, value: 3 }]
点击删除之后的数组是 [{ id: 1, value: 1 }, { id: 3, value: 3 }]

  • 首先发现 id 从 1 2 3 变成了 1 3,说明第二项被删除了
  • 然后依次对此 id: 1 的项和 id: 3 的项,发现没变化。

所以计算机得出结论:第二项被删除了。符合预期!

总结

当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key的作用让每个item有一个唯一的识别身份,可以下标值index或者id, 主要是为了vue精准的追踪到每一个元素,高效的更新虚拟DOM。

Logo

前往低代码交流专区

更多推荐