v-for 关联的数组增加新元素时,已有元素对应的 DOM 节点是否会被重新渲染?

2020-12-19 16:10:13 +08:00
 dream4ever

比如我需要实时显示飞机航线,代码设定为每隔 1 分钟从后端获取一次飞机在这 1 分钟内的航线数据,并调用 push()方法将数据添加到数组 trail 中。

那么我在第 11 分钟获取到数据并 push 进变量 trail 之后,之前已经渲染出来的前 10 分钟的航线所对应的 DOM 节点,是否会被重新渲染呢?

另外,不管结论是“已有的 DOM 节点会被重新渲染”,还是“不会被重新渲染”,我该如何验证这个结论呢?看了 Vue 官方文档关于列表渲染的部分,提到它用的是"in-place patch"策略,看起来我举的例子中,已有的 DOM 节点不会被重新渲染,但还是希望能够有确实的证据能证明我的想法。

谢谢先。

2608 次点击
所在节点    Vue.js
14 条回复
meathill
2020-12-19 16:39:44 +08:00
所以要用 `:key`,仔细看文档。
wunonglin
2020-12-19 16:57:45 +08:00
for 的时候要用 key 。

key 可以设置为你数据源的 id,这样你刷新数据只有 id 变的才重新渲染。没设置 key,数据变的时候会全部渲染。

当然也不建议设置 for 的 index 为 key 值,因为数据源变的时候 for 的 index 是对不上渲染出来的数据的,结果还是重新渲染
wunonglin
2020-12-19 16:59:15 +08:00
如何验证的话你直接看控制台的 dom 有没有变化即可
dream4ever
2020-12-19 17:19:07 +08:00
@wunonglin 那么有没有一个 hook 或者 callback 或者别的什么函数,让我可以明确地知道“这个 DOM 节点此刻被重新渲染了”呢?现在是想弄清楚一件事,就是我对 v-for 所绑定的数组做各种操作,想明确地知道什么时候各个 DOM 节点被重新渲染了,什么时候没有被重新渲染,希望能找到这么一个 event 或者别的什么,作为确切的证据。
wunonglin
2020-12-19 17:44:45 +08:00
@dream4ever #4

这个就不太清楚了,我看人家尤大也是在控制台看 dom 变化的。

https://cn.vuejs.org/v2/api/#key
在文档我看到他那个例子有 transition,你要不试试在每个 item 包一个 transition 动画,移除和新增的时候应该能看到动画的变化,我没试过,你可以试试
wunonglin
2020-12-19 17:55:23 +08:00
Thexz
2020-12-19 20:39:43 +08:00
test
walpurgis
2020-12-19 23:50:14 +08:00
把 dom 节点用变量存起来,数据更新后获取新的节点,跟旧的比较是否相等,就知道是不是更新过了
no1xsyzy
2020-12-20 02:04:04 +08:00
key 设置好的话会根据 key 匹配。
否则 Vue 会自行想方设法匹配。

如果要严格强硬的探测,你可以用 ECMA 的 MutationObserver
或者在生命周期钩子里面选你需要的(大概),但是需要你写成 component
agdhole
2020-12-20 12:29:47 +08:00
key 如果为 string,比如 key.title,会不会造成性能问题?
DFshpAq3
2020-12-20 21:06:07 +08:00
@no1xsyzy 您好,能请教一下自行想方设法匹配具体是什么过程吗?文档里没写清楚,很想知道
a62527776a
2020-12-20 21:26:59 +08:00
如果附上了 key 的话 Vue 保存一份 key 和下标的 map
diff 的时候 拿着新老虚拟 dom 比较
如果 key 相等 下标变了 只会移动真实 dom
如果是新 key 会创建真实 dom
rodrick
2020-12-21 08:38:55 +08:00
如果没有设置 key,会按照默认的节点 index 去 diff,假设你中间插入一个数据,那么插入的数据的节点 dom 后面的都会重新渲染,另外 key 不能用迭代对象的 index
no1xsyzy
2020-12-21 11:33:46 +08:00
@DFshpAq3 首先,不要依赖 undocumented behavior
如果你是好奇,还是看源代码吧

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/737060

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX