dream4ever
V2EX  ›  Vue.js

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

  •  
  •   dream4ever · Dec 19, 2020 · 3210 views
    This topic created in 1985 days ago, the information mentioned may be changed or developed.

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

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

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

    谢谢先。

    14 replies    2020-12-21 11:33:46 +08:00
    meathill
        1
    meathill  
       Dec 19, 2020
    所以要用 `:key`,仔细看文档。
    shakaraka
        2
    shakaraka  
    PRO
       Dec 19, 2020
    for 的时候要用 key 。

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

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

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

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

    如果要严格强硬的探测,你可以用 ECMA 的 MutationObserver
    或者在生命周期钩子里面选你需要的(大概),但是需要你写成 component
    agdhole
        10
    agdhole  
       Dec 20, 2020 via iPhone
    key 如果为 string,比如 key.title,会不会造成性能问题?
    DFshpAq3
        11
    DFshpAq3  
       Dec 20, 2020
    @no1xsyzy 您好,能请教一下自行想方设法匹配具体是什么过程吗?文档里没写清楚,很想知道
    a62527776a
        12
    a62527776a  
       Dec 20, 2020
    如果附上了 key 的话 Vue 保存一份 key 和下标的 map
    diff 的时候 拿着新老虚拟 dom 比较
    如果 key 相等 下标变了 只会移动真实 dom
    如果是新 key 会创建真实 dom
    rodrick
        13
    rodrick  
       Dec 21, 2020
    如果没有设置 key,会按照默认的节点 index 去 diff,假设你中间插入一个数据,那么插入的数据的节点 dom 后面的都会重新渲染,另外 key 不能用迭代对象的 index
    no1xsyzy
        14
    no1xsyzy  
       Dec 21, 2020
    @DFshpAq3 首先,不要依赖 undocumented behavior
    如果你是好奇,还是看源代码吧
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5391 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 86ms · UTC 07:00 · PVG 15:00 · LAX 00:00 · JFK 03:00
    ♥ Do have faith in what you're doing.