diff --git a/packages/runtime-core/__tests__/apiWatch.spec.ts b/packages/runtime-core/__tests__/apiWatch.spec.ts index f24ce80b9df..7a7e88032d9 100644 --- a/packages/runtime-core/__tests__/apiWatch.spec.ts +++ b/packages/runtime-core/__tests__/apiWatch.spec.ts @@ -1205,4 +1205,39 @@ describe('api: watch', () => { expect(countWE).toBe(3) expect(countW).toBe(2) }) + + // #5151 + test('OnCleanup also needs to be cleaned,', async () => { + const spy1 = vi.fn() + const spy2 = vi.fn() + const num = ref(0) + + watch(num, (value, oldValue, onCleanup) => { + if (value > 1) { + return + } + spy1() + onCleanup(() => { + // OnCleanup also needs to be cleaned + spy2() + }) + }) + + num.value++ + await nextTick() + expect(spy1).toHaveBeenCalledTimes(1) + expect(spy2).toHaveBeenCalledTimes(0) + + num.value++ + await nextTick() + + expect(spy1).toHaveBeenCalledTimes(1) + expect(spy2).toHaveBeenCalledTimes(1) + + num.value++ + await nextTick() + // would not be calld when value>1 + expect(spy1).toHaveBeenCalledTimes(1) + expect(spy2).toHaveBeenCalledTimes(1) + }) }) diff --git a/packages/runtime-core/src/apiWatch.ts b/packages/runtime-core/src/apiWatch.ts index 1b85ba12d19..71b15fd6e04 100644 --- a/packages/runtime-core/src/apiWatch.ts +++ b/packages/runtime-core/src/apiWatch.ts @@ -273,10 +273,11 @@ function doWatch( getter = () => traverse(baseGetter()) } - let cleanup: () => void + let cleanup: (() => void) | undefined let onCleanup: OnCleanup = (fn: () => void) => { cleanup = effect.onStop = () => { callWithErrorHandling(fn, instance, ErrorCodes.WATCH_CLEANUP) + cleanup = effect.onStop = undefined } }