]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(reactivity): ensure watch(Effect) can run independent of unmounted instance if...
authorThorsten Lünborg <t.luenborg@googlemail.com>
Mon, 9 Jan 2023 14:20:21 +0000 (15:20 +0100)
committerGitHub <noreply@github.com>
Mon, 9 Jan 2023 14:20:21 +0000 (15:20 +0100)
* fix(reactivity): ensure watch(Effect) can run independent of unmounted instance if created in a detatched effectScope

* test: use separate counters for each watcher to make test more robust

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

index f6bad14ddb9b8621b5720a03095e2d1904d9a182..6de8f95dec6e66da2610d16683759c805c6e6ff7 100644 (file)
@@ -1150,4 +1150,44 @@ describe('api: watch', () => {
     // own update effect
     expect(instance!.scope.effects.length).toBe(1)
   })
+
+  test('watchEffect should keep running if created in a detatched scope', async () => {
+    const trigger = ref(0)
+    let countWE = 0
+    let countW = 0
+    const Comp = {
+      setup() {
+        effectScope(true).run(() => {
+          watchEffect(
+            () => {
+              trigger.value
+              countWE++
+            },
+          )
+          watch(
+            trigger,
+            () => countW++
+          )
+        })
+        return () => ''
+      }
+    }
+    const root = nodeOps.createElement('div')
+    render(h(Comp), root)
+     // only watchEffect as ran so far
+    expect(countWE).toBe(1)
+    expect(countW).toBe(0)
+    trigger.value++
+    await nextTick()
+    // both watchers run while component is mounted
+    expect(countWE).toBe(2)
+    expect(countW).toBe(1)
+    render(null, root) // unmount
+    await nextTick()
+    trigger.value++
+    await nextTick()
+     // both watchers run again event though component has been unmounted
+    expect(countWE).toBe(3)
+    expect(countW).toBe(2)
+  })
 })
index ce13f0bb80531902a4d463b5c2bd211086f48e23..a85e0e93be6795819fef99f6c1db7db939807840 100644 (file)
@@ -7,7 +7,8 @@ import {
   isReactive,
   ReactiveFlags,
   EffectScheduler,
-  DebuggerOptions
+  DebuggerOptions,
+  getCurrentScope,
 } from '@vue/reactivity'
 import { SchedulerJob, queueJob } from './scheduler'
 import {
@@ -197,7 +198,8 @@ function doWatch(
     )
   }
 
-  const instance = currentInstance
+  const instance = getCurrentScope() === currentInstance?.scope ?  currentInstance : null
+  // const instance = currentInstance
   let getter: () => any
   let forceTrigger = false
   let isMultiSource = false