]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(watch): cleanup watcher effect from scope when manually stopped (#9978)
authorYang Mingshan <y.mingshan3@gmail.com>
Thu, 4 Jan 2024 02:36:13 +0000 (10:36 +0800)
committerGitHub <noreply@github.com>
Thu, 4 Jan 2024 02:36:13 +0000 (10:36 +0800)
packages/runtime-core/__tests__/apiWatch.spec.ts
packages/runtime-core/src/apiWatch.ts

index 3656b0a64bac2ac5698ffe468180767a1bc5758e..fe299edbb63423e615684ef4f7ec97e070fe2881 100644 (file)
@@ -1443,4 +1443,35 @@ describe('api: watch', () => {
     expect(spy1).toHaveBeenCalledTimes(1)
     expect(spy2).toHaveBeenCalledTimes(1)
   })
+
+  test("effect should be removed from scope's effects after it is stopped", () => {
+    const num = ref(0)
+    let unwatch: () => void
+
+    let instance: ComponentInternalInstance
+    const Comp = {
+      setup() {
+        instance = getCurrentInstance()!
+        unwatch = watch(num, () => {
+          console.log(num.value)
+        })
+        return () => null
+      },
+    }
+    const root = nodeOps.createElement('div')
+    createApp(Comp).mount(root)
+    expect(instance!.scope.effects.length).toBe(2)
+    unwatch!()
+    expect(instance!.scope.effects.length).toBe(1)
+
+    const scope = effectScope()
+    scope.run(() => {
+      unwatch = watch(num, () => {
+        console.log(num.value)
+      })
+    })
+    expect(scope.effects.length).toBe(1)
+    unwatch!()
+    expect(scope.effects.length).toBe(0)
+  })
 })
index 7fbcc78f36fb9ad25e1fb4190e880f1e4fc6829a..3a2d9e46c3382cd63b24048ea117b6c7a8521256 100644 (file)
@@ -5,6 +5,7 @@ import {
   ReactiveEffect,
   ReactiveFlags,
   type Ref,
+  getCurrentScope,
   isReactive,
   isRef,
   isShallow,
@@ -394,10 +395,11 @@ function doWatch(
 
   const effect = new ReactiveEffect(getter, NOOP, scheduler)
 
+  const scope = getCurrentScope()
   const unwatch = () => {
     effect.stop()
-    if (instance && instance.scope) {
-      remove(instance.scope.effects!, effect)
+    if (scope) {
+      remove(scope.effects, effect)
     }
   }