]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(reactivity): onCleanup also needs to be cleaned (#8655)
author花果山大圣 <316783812@qq.com>
Fri, 10 Nov 2023 08:47:08 +0000 (16:47 +0800)
committerGitHub <noreply@github.com>
Fri, 10 Nov 2023 08:47:08 +0000 (16:47 +0800)
close #5151
close #7695

packages/runtime-core/__tests__/apiWatch.spec.ts
packages/runtime-core/src/apiWatch.ts

index dcb1d6a5f28422ef434df70a5e5256d49fffdd22..48fdd2888ec02df65bddca2e9513925a8bf2d0e2 100644 (file)
@@ -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)
+  })
 })
index 1b85ba12d19b66586a38e10cb144f18f57758799..71b15fd6e0448ad701f0361114228fb17c97b380 100644 (file)
@@ -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
     }
   }