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

2021-12-21  本文已影响0人  tian田小旺

前言

众所周知,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
上一篇下一篇

猜你喜欢

热点阅读