美文网首页
记一个Vue版本升级导致的bug——Vue的异步处理

记一个Vue版本升级导致的bug——Vue的异步处理

作者: tian田小旺 | 来源:发表于2021-12-21 19:00 被阅读0次

    前言

    众所周知,Vue 在内部维护了一套异步任务队列。

    仔细查看 Vue 的changelog 知道:

    现象

    点击【更多】不出现菜单了。

    image2021-12-21_17-26-2.png image2021-12-21_17-26-49.png

    伪代码

    image2021-12-21_17-40-51.png

    排查

    1. 控制台未报错,排除代码逻辑错误;
    2. TSS 30102 之前该功能测试正常,TSS 30102 没有重保模块的需求,所以代码没有改动,排除代码修改的原因;
    3. 查看 vue-devtools 发现 isShowMoreTool 先改变为 true , 后又变为 false。现象就是 mouseover 和 mouseout 事件改变 isShowTool,watch 监听器函数执行,将菜单隐藏。
    4. 我知道 TSS 30102 中,因为引入 qaxd ,将 Vue 从 2.5 升级到了 2.6。切换不同版本 Vue 测试,果然和Vue 版本有关。

    原因

    1. 子元素的显示隐藏会触发父元素的 mouseout、mouseover 事件。
    2. Vue 2.5 中,watch 监听器使用 macrotask 宏任务实现。
      1. 在子元素的 click 回调(isShowMoreTool === true)之后,菜单显示
      2. 触发mouseout(false)、mouseover (true)两个事件回调
      3. 之后再执行 watch 监听器,发现监听数据的值未发生改变(isShowTool === true),所以菜单如期望显示(isShowMoreTool === true)。
    3. Vue 2.6 中,watch 监听器使用 microtask 微任务实现。
      1. 在子元素的 click 回调(isShowMoreTool === true)之后,菜单显示
      2. 触发mouseout、watch
      3. 触发 mouseover、watch
      4. 执行完毕之后,菜单不显示 (isShowMoreTool === false)

    解决方案

    结合业务场景,修改 mouseover 为 mouseenter,修改 mouseout 为 mouseleave。子元素显示隐藏不会触发父元素mouseleave 事件。

    Element: mouseenter event - Web APIs | MDN (mozilla.org)

    image2021-12-21_17-26-2.png

    相关文章

      网友评论

          本文标题:记一个Vue版本升级导致的bug——Vue的异步处理

          本文链接:https://www.haomeiwen.com/subject/idnxqrtx.html