]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(reactivity): ensure watcher with once: true are properly removed from effect...
authoryangxiuxiu <79584569+yangxiuxiu1115@users.noreply.github.com>
Tue, 20 Aug 2024 08:35:08 +0000 (16:35 +0800)
committerGitHub <noreply@github.com>
Tue, 20 Aug 2024 08:35:08 +0000 (16:35 +0800)
packages/reactivity/src/watch.ts
packages/runtime-core/__tests__/apiWatch.spec.ts

index 96da5ffe5c23e91a4171d9611ad43f11dde8ac76..9c1eea00b9b7d6fafc0f4975b2321cd72cfcc3f9 100644 (file)
@@ -206,18 +206,26 @@ export function watch(
     getter = () => traverse(baseGetter(), depth)
   }
 
+  const scope = getCurrentScope()
+  const watchHandle: WatchHandle = () => {
+    effect.stop()
+    if (scope) {
+      remove(scope.effects, effect)
+    }
+  }
+
   if (once) {
     if (cb) {
       const _cb = cb
       cb = (...args) => {
         _cb(...args)
-        effect.stop()
+        watchHandle()
       }
     } else {
       const _getter = getter
       getter = () => {
         _getter()
-        effect.stop()
+        watchHandle()
       }
     }
   }
@@ -317,14 +325,6 @@ export function watch(
     effect.run()
   }
 
-  const scope = getCurrentScope()
-  const watchHandle: WatchHandle = () => {
-    effect.stop()
-    if (scope) {
-      remove(scope.effects, effect)
-    }
-  }
-
   watchHandle.pause = effect.pause.bind(effect)
   watchHandle.resume = effect.resume.bind(effect)
   watchHandle.stop = watchHandle
index b1eb85f8a130cc382c0b2f446f20c7c5dfef8d9b..7a800949eea8983592ed632f153f71ce1d6b0a5f 100644 (file)
@@ -1771,6 +1771,11 @@ describe('api: watch', () => {
     expect(scope.effects.length).toBe(1)
     unwatch!()
     expect(scope.effects.length).toBe(0)
+
+    scope.run(() => {
+      watch(num, () => {}, { once: true, immediate: true })
+    })
+    expect(scope.effects.length).toBe(0)
   })
 
   // simplified case of VueUse syncRef