前端前線 2026 年 10 月 17 日

2026-10-17 — Vue 3.6.0-rc.12 修正 watch 清理時機回歸,Vapor 補轉場案例

primary=https://github.com/vuejs/core/releases/tag/v3.6.0-rc.12 primary=https://github.com/vuejs/core/blob/minor/CHANGELOG.md primary=https://github.com/vuejs/core/issues/15765 primary=https://github.com/vuejs/core/pull/15766

Vue 3.6.0-rc.12 修正 watch 清理時機的回歸,Vapor 補上轉場邊角案例

Vue core GitHub Release · 2026-10-16

Vue 3.6 在 watch 的清理(cleanup)時機上多了一個回歸:getter 重新求值但值沒變時,onCleanup 會被提早執行。這個問題在 v3.6.0-rc.12 由 #15766 修正,讓行為回到 3.5 的語意。

rc.12 的 CHANGELOG 日期是 2026-10-16,Release 頁本身只指向該檔案,沒有另寫說明。

原本的問題

回報者在 #15765 指出,3.6.0-alpha.1 到 rc.10 都有此現象,3.5.43 則正常。條件很單純:watch 的來源是 getter,getter 重跑後回傳值與上次相同,所以 cb 不會被呼叫,但清理函式卻已被執行。

清理函式的用途是撤銷上一次 cb 留下的副作用,例如取消請求、移除事件監聽。照契約,它應該在「下一次 cb 執行前」或「watcher 停止時」才跑。值沒變、cb 沒跑,就代表上一次的副作用仍然有效,此時清掉會讓資源提前失效。

issue 的重現程式如下,兩個版本的輸出順序不同:

const a = ref(1)
watch(() => a.value > 0, (v, _, onCleanup) => {
  onCleanup(() => log.push('onCleanup'))
}, { immediate: true })
a.value++   // getter 仍為 true,cb 不會重跑
scope.stop()
版本a.value++ 之後scope.stop() 之後
3.5.43無清理onCleanup、onWatcherCleanup
3.6.0-rc.10onCleanup、onWatcherCleanup無

核心改動

PR 14cfe0f 的標題是「preserve watcher cleanups until callback reruns」。依 PR 摘要,當被監看的值沒變時,清理回呼會被保留,等到下一次 cb 執行前或 watcher 停止時才跑。

PR 摘要另外提到兩點:effect 本身的清理與 cb 的清理改為分開處理;混合註冊時,重跑或停止會依註冊順序執行,重複 stop 不會再跑一次。pre、post、sync 三種 flush 模式行為一致。摘要為自動產生,細節請以 diff 為準。

Vapor 的轉場與 KeepAlive

rc.12 的 Bug Fixes 大半是 runtime-vapor,集中在 Transition 與 KeepAlive 的組合:例如 #15895 讓 KeepAlive 分支的 in-out 離場在新元素進場之後才開始,#15866 讓 interop 片段等離場動畫結束才移除,#15867 改為從節點實際的 parentNode 移除 block。

這些修正指向同一件事:Vapor 與 vdom 混用(interop)時,動畫的先後與節點歸屬仍是主要不穩定來源。上一版 rc.11(2026-10-10)才新增「在 vdom Transition 內轉場 Vapor slot 內容」的功能(#15758),rc.12 緊接著補邊角案例,符合這個脈絡。

影響範圍

  • 已在 3.6 prerelease 上用 watch 搭配 getter 的專案:檢查 onCleanup 或 onWatcherCleanup 內有沒有取消請求、解除訂閱之類的動作。rc.10 及更早版本它們可能在值未變時被提早觸發,你的程式碼若已為此加了繞路,升到 rc.12 後可以拿掉。
  • 在 vdom 應用中以 interop 嘗鮮 Vapor 元件的團隊:若遇過 KeepAlive 切換後離場動畫沒做完、節點殘留或 slot 在 out-in 下閃爍,可對照上述 PR 編號重測。
  • 用 Vapor 做 SSR 的專案:#15852 修正動態原生元素的子節點在 SSR 的輸出方式,hydration 不一致的問題可以重測。
  • 想看 client bundle 體積的人:#15875 讓 hydration 查找用的 DOM 節點 helper 可被 tree-shake,數字 changelog 未提供。

要驗證自己是否中招,最快的做法是把上面的重現程式貼進專案,分別在 rc.10 與 rc.12 跑,比對清理出現的位置。Release notes 未說明 3.6 正式版的發布時間。

原始來源:Release v3.6.0-rc.12、minor 分支 CHANGELOG、Issue #15765、PR #15766


End of article
0
Would love your thoughts, please comment.x
()
x