前言
眾所周知,Vue 在內(nèi)部維護(hù)了一套異步任務(wù)隊(duì)列。
仔細(xì)查看 Vue 的changelog 知道:
- 在 v2.4的時(shí)候,其使用 microtask 實(shí)現(xiàn)。
- 由于一些bug,在 v2.5 改為了使用 macrotask 實(shí)現(xiàn)。
- 又由于導(dǎo)致了得不償失的bug,在 v2.6 Release v2.6.0 Macross · vuejs/vue (github.com) 改回使用 microtask 了。(details)
現(xiàn)象
點(diǎn)擊【更多】不出現(xiàn)菜單了。

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

image2021-12-21_17-26-49.png
偽代碼

image2021-12-21_17-40-51.png
排查
- 控制臺(tái)未報(bào)錯(cuò),排除代碼邏輯錯(cuò)誤;
- TSS 30102 之前該功能測(cè)試正常,TSS 30102 沒有重保模塊的需求,所以代碼沒有改動(dòng),排除代碼修改的原因;
- 查看 vue-devtools 發(fā)現(xiàn) isShowMoreTool 先改變?yōu)?true , 后又變?yōu)?false?,F(xiàn)象就是 mouseover 和 mouseout 事件改變 isShowTool,watch 監(jiān)聽器函數(shù)執(zhí)行,將菜單隱藏。
- 我知道 TSS 30102 中,因?yàn)橐?qaxd ,將 Vue 從 2.5 升級(jí)到了 2.6。切換不同版本 Vue 測(cè)試,果然和Vue 版本有關(guān)。
原因
- 子元素的顯示隱藏會(huì)觸發(fā)父元素的 mouseout、mouseover 事件。
- Vue 2.5 中,watch 監(jiān)聽器使用 macrotask 宏任務(wù)實(shí)現(xiàn)。
- 在子元素的 click 回調(diào)(isShowMoreTool === true)之后,菜單顯示
- 觸發(fā)mouseout(false)、mouseover (true)兩個(gè)事件回調(diào)
- 之后再執(zhí)行 watch 監(jiān)聽器,發(fā)現(xiàn)監(jiān)聽數(shù)據(jù)的值未發(fā)生改變(isShowTool === true),所以菜單如期望顯示(isShowMoreTool === true)。
- Vue 2.6 中,watch 監(jiān)聽器使用 microtask 微任務(wù)實(shí)現(xiàn)。
- 在子元素的 click 回調(diào)(isShowMoreTool === true)之后,菜單顯示
- 觸發(fā)mouseout、watch
- 觸發(fā) mouseover、watch
- 執(zhí)行完畢之后,菜單不顯示 (isShowMoreTool === false)
解決方案
結(jié)合業(yè)務(wù)場(chǎng)景,修改 mouseover 為 mouseenter,修改 mouseout 為 mouseleave。子元素顯示隱藏不會(huì)觸發(fā)父元素mouseleave 事件。
Element: mouseenter event - Web APIs | MDN (mozilla.org)

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