求助, vue 轮询请求更新数据渲染时闪烁 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的容
SanGo
V2EX    程序员

求助, vue 轮询请求更新数据渲染时闪烁

  •  
  • /div>   SanGo 2019-07-05 09:06:49 +08:00 6880 次点击
    这是一个创建于 2370 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我遇到一个问题,做一个监控平台,采用轮询请求更新 data,但是由于相关联的视图试用 vfor 渲染的,更新视图时会导致闪烁更新,搜过狗哥也没解决方案,还请大佬们指点一下
    第 1 条附言    2019-07-05 10:56:25 +08:00

    code1code2code3code4code5

    第 2 条附言    2019-07-05 11:03:01 +08:00
    这个是当前的问题,因为 data 的更新会导致重新渲染,然后发生闪烁,这块的话父级和子级都要分别获取,先定时轮询父级然后触发 watch 去变更 data 触发子级的请求
    ![show1]( https://s2.ax1x.com/2019/07/05/ZaaObR.png)
    ![show2]( https://s2.ax1x.com/2019/07/05/ZaavUx.png)
    47 条回复    2019-07-05 15:26:26 +08:00
    jorneyr
        1
    jorneyr  
       2019-07-05 09:10:52 +08:00
    试试 throttle 或者 debounce 进行节流,避免频繁更新,可以使用 underscore 或者 lodash 的实现,也可以自己实现这 2 个函数,参考 https://underscorejs.org/#throttle
    NaVient
        2
    NaVient  
       2019-07-05 09:13:18 +08:00
    是你想的太复杂了把,这不就是更新数据先声明成临时变量,再循环去看页面数据和更新数据不同的地方,更新数据变更的项不就行了吗?
    clandyuki
        3
    clandyuki  
       2019-07-05 09:14:13 +08:00
    加上 key
    SanGo
        4
    SanGo  
    OP
       2019-07-05 09:29:24 +08:00
    @jorneyr 是定时更新的,所以不用节流
    SanGo
        5
    SanGo  
    OP
       2019-07-05 09:31:52 +08:00
    @NaVient 绑定的 data 发生变化,就会重新触发 v-for 去渲染导致闪烁
    @clandyuki vfor 加 key 很常规啊。。。
    15651980765
        6
    15651980765  
       2019-07-05 09:34:22 +08:00
    v-for 的时候绑定 key,值用数据的 id,不要用遍历的索引,这样可以保证数据变化后可以最大程度复用之前的 DOM。
    NaVient
        7
    NaVient  
       2019-07-05 09:35:00 +08:00
    @SanGo #5 你不变更 data 整体,变更 data 的一个 index 不会触发的,VUE 内部是根据 key 去更新的
    shenyu1996
        8
    shenyu1996  
       2019-07-05 09:37:32 +08:00
    是不是 data 更新前顺便赋了个 null
    TrickWu
        9
    TrickWu  
       2019-07-05 09:44:34 +08:00
    照理不会闪烁的,是根据 data 变化来触发视图更新,应该是你代码写的有问题
    Vegetable
        10
    Vegetable  
       2019-07-05 09:46:24 +08:00
    上代码吧兄弟
    cuzfinal
        11
    cuzfinal  
       2019-07-05 09:49:15 +08:00
    这种引发列表重新渲染的肯定是用了不稳定 key,代码都不用看。
    no1xsyzy
        12
    no1xsyzy  
       2019-07-05 09:58:53 +08:00
    先复制一份然后尽可能缩,产生一份最小可复现样本。
    如果如 #8 所言,或者类似地更新操作导致 data 暂时地不可用化,应该会在 console 里有报错,或者有 v-if="data"。
    另外闪烁的样子录个 gif 吧,有可能甚至跟前端无关,是硬件跟不上也有可能。
    qiaobeier
        13
    qiaobeier  
       2019-07-05 09:59:52 +08:00
    尝试闪烁的节点上加上 css 属性 transform: translateZ(0);
    p8YFk4f3E8SJ3aEv
        14
    p8YFk4f3E8SJ3aEv  
       2019-07-05 10:00:09 +08:00
    我的 key 都是 item.index,而且很少使用
    jorneyr
        15
    jorneyr  
       2019-07-05 10:01:26 +08:00   3
    代码那点破事真不是难事,码农更重要的是学会沟通,不要抱怨没人回答你的问题,
    首先需要学会如何提问,其他人才能更好的理解你的问题。

    如何有效地提问:
    - 你做了什么,怎么做的
    - 你查过什么资料,怎么说的
    - 你是怎么设计的
    - 贴出你的代码
    - 编译错误是什么
    - 代码截图,错误截图
    - 结果有什么错,你期望的结果是什么
    - 你是怎么想的

    回答你的问题是情义,不理你是我的权力,没有人有义务要帮助你
    你是在寻求帮助,态度好点,但也不要委屈自己

    最后,如果你啥都不会,或者只会一点基础,不要期望我们告诉你怎么做
    sugars
        16
    sugars  
    PRO
       2019-07-05 10:16:21 +08:00
    楼上正解,就提问者提供的信息,不够详情,无从下手(就这情况,更新时加了动画 css 也不是不可能)
    a852695
        17
    a852695  
       2019-07-05 10:18:35 +08:00
    能否贴个 GIF 和对应的部分代码,这样问题也好定位
    SanGo
        18
    SanGo  
    OP
       2019-07-05 10:43:12 +08:00
    不知道 V2EX 怎么上图。。。
    SanGo
        19
    SanGo  
    OP
       2019-07-05 11:07:18 +08:00
    我现在把这边的 key 改成了 index 了,依然会导致闪烁 Orz
    https://s2.ax1x.com/2019/07/05/ZawEy4.png
    SanGo
        20
    SanGo  
    OP
       2019-07-05 11:07:51 +08:00
    @sugars css 没加=-=。。
    SanGo
        21
    SanGo  
    OP
       2019-07-05 11:10:19 +08:00
    @shenyu1996 data 更新前没有做赋值操作,初始渲染的时候是为空的不用管
    SanGo
        22
    SanGo  
    OP
       2019-07-05 11:13:32 +08:00
    ytxbnahn
        23
    ytxbnahn  
       2019-07-05 11:28:32 +08:00
    更新数据时 你是不是先初始化了 data=[] 然后在重新赋值.@SanGo
    SanGo
        24
    SanGo  
    OP
       2019-07-05 11:35:21 +08:00
    @ytxbnahn 没有,只有第一次加载的时候是有初始化的,更新的时候没有初始化 data,代码在附加的图里面
    wdspro
        25
    wdspro  
       2019-07-05 11:38:54 +08:00
    @SanGo 楼上整理了三种可能
    一个是你的 key 尽量不要用 index 用用其他的 ID 啥的 尽量减少重绘
    二就是你取回新的 data 前是不是有初始化数组为[] 肯定就又完完整整重新渲染了两次 会闪烁
    第三种就是有可能硬件有影响 数据量太大的时候 排除方式是最小化自己的数据量来例化测一下 楼上说的 transfromZ 也有可能
    别着急问 先看看大家的回答 这么多楼了 你的 key 还没改试一下
    wdspro
        26
    wdspro  
       2019-07-05 11:40:29 +08:00
    你的图里 第二个 for 循环里怎么有两个:key
    SanGo
        28
    SanGo  
    OP
       2019-07-05 12:27:22 +08:00
    @wdspro 哦哦,现在第二个 for 现在改了,还是一样的
    1.不用 key 的话用 item.id 这类的 key 也会因为 data 的对象导致更新
    2.去会心的 data 前没有初始化数组
    3.数据量在#22 的图有...非常少
    ASpiral
        29
    ASpiral  
       2019-07-05 12:28:55 +08:00
    点开第一张图就看到 :key="item.CtiNo + i",key 不要用到 index …
    SanGo
        30
    SanGo  
    OP
       2019-07-05 12:30:40 +08:00
    @jorneyr 设计和效果都上了附图了,附 1 是代码,附 2 和#22 是效果,
    搜索过 data 更新闪烁,大多数都是说采用 v-cloak 来解决,但是我这里不是初始化的空白闪烁问题,是更新数据的异步闪烁 Orz,期望#22 的数据更新时不发生闪烁,该代码目标是实现监控组通话数量(数量还没绑定进去渲染),谢谢
    SanGo
        31
    SanGo  
    OP
       2019-07-05 12:33:14 +08:00
    关于各位说到的 key 不要用到 index 的问题,现在已经改成了下图
    https://s2.ax1x.com/2019/07/05/ZagvC9.png
    也没有改变结果 Orz
    no1xsyzy
        32
    no1xsyzy  
       2019-07-05 12:57:44 +08:00
    res.Cti 的值是?
    你还说没有先清空再添加?
    SanGo
        33
    SanGo  
    OP
       2019-07-05 13:04:42 +08:00
    @no1xsyzy 直接赋值呀。。是个数组包对象
    no1xsyzy
        34
    no1xsyzy  
       2019-07-05 13:10:36 +08:00   1
    你用了两个接口去获取
    一个 getCti 一个 getTrunk
    你先把 getCti 的结果填充进去,然后再去获取的 getTrunk
    我有理由相信 getCti 本身没有 Trunk 的信息,所以 Trunk 被清空了,然后又通过 watch 添加的,中间必然差至少一帧。
    no1xsyzy
        35
    no1xsyzy  
       2019-07-05 13:12:22 +08:00
    这个问题不管是开 vue debugger (浏览器插件)还是开 Network 选项卡都是可以轻易得知的。
    jorneyr
        36
    jorneyr  
       2019-07-05 13:12:46 +08:00
    看不出问题来,如果可能的话, 弄一个最小的测试案例,大家可以重现,然后才能去调试。
    数据模拟生成就好,不用走服务器端
    SanGo
        37
    SanGo  
    OP
       2019-07-05 13:16:06 +08:00
    @no1xsyzy 是的,是这个问题 Orz 所以难以处理这块
    no1xsyzy
        38
    no1xsyzy  
       2019-07-05 13:18:21 +08:00
    @SanGo 这难解决?请回炉重造(指程序员)。
    lhstock
        39
    lhstock  
       2019-07-05 13:20:08 +08:00
    watch 监听 CTI 又修改 CTI 是作死
    SanGo
        40
    SanGo  
    OP
       2019-07-05 13:21:45 +08:00
    @no1xsyzy 给多一个变量拿到 trunk 插入 cti 以后再直接替换是可以,但是感觉都是绕了一圈- -
    crs0910
        41
    crs0910  
       2019-07-05 13:25:41 +08:00
    liuy1994g
        42
    liuy1994g  
       2019-07-05 13:26:55 +08:00 via Android
    求求你打开控制台看看 network 到底发了多少个请求吧。
    你在 watch 里面对每一项都重新取值了。
    SanGo
        43
    SanGo  
    OP
       2019-07-05 13:30:47 +08:00
    @liuy1994g #34 说了
    crs0910
        44
    crs0910  
       2019-07-05 13:31:55 +08:00
    你可以不用 watch,第一级拿完直接拿第二级返回完整数据不就得了。我看你都不关心 id 是不是变了,每次都是拿的全量新数据。那就直接都拿完拼完呗。
    no1xsyzy
        45
    no1xsyzy  
       2019-07-05 13:32:27 +08:00   1
    @SanGo 还有一种就是把 CTI 和 Trunk 分开存两个属性里,分别更新。
    但那样其实就是自己手工写一个简陋、粗糙、残缺、低效的关系型数据库。
    为什么不让后端做?一件事多个接口还不是做成 RESTful 的。
    graphQL 或者 RESTful 你总得选一个。
    SanGo
        46
    SanGo  
    OP
       2019-07-05 13:34:56 +08:00
    @no1xsyzy 后端表示反正给我了....然后就 emmm,graphQL 我看一看如何处理,谢谢解答
    a4854857
        47
    a4854857  
       2019-07-05 15:26:26 +08:00
    看了楼上的你的渲染数据如果是两个接口的数据拼成的. 你用 promise.all 保证一次两个请求都返回值了再更新数据不就好了..
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2784 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 14:42 PVG 22:42 LAX 06:42 JFK 09:42
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86