V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
dream4ever
V2EX  ›  Vue.js

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

  •  
  •   dream4ever · 2020-12-19 16:10:13 +08:00 · 2473 次点击
    这是一个创建于 1216 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    谢谢先。

    14 条回复    2020-12-21 11:33:46 +08:00
    meathill
        1
    meathill  
       2020-12-19 16:39:44 +08:00
    所以要用 `:key`,仔细看文档。
    wunonglin
        2
    wunonglin  
       2020-12-19 16:57:45 +08:00
    for 的时候要用 key 。

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

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

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

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

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