]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(reactivity): ensure multiple effectScope `on()` and `off()` calls maintains corre...
authoredison <daiwei521@126.com>
Wed, 8 Jan 2025 10:03:40 +0000 (18:03 +0800)
committerGitHub <noreply@github.com>
Wed, 8 Jan 2025 10:03:40 +0000 (18:03 +0800)
packages/reactivity/__tests__/effectScope.spec.ts
packages/reactivity/src/effectScope.ts

index debbdafb1e70bbef3529729f5061fb211490ccf0..84310b985f25faf1fa3c86b99bc9b01329f4bf81 100644 (file)
@@ -296,6 +296,19 @@ describe('reactivity/effect/scope', () => {
     })
   })
 
+  it('calling on() and off() multiple times inside an active scope should not break currentScope', () => {
+    const parentScope = effectScope()
+    parentScope.run(() => {
+      const childScope = effectScope(true)
+      childScope.on()
+      childScope.on()
+      childScope.off()
+      childScope.off()
+      childScope.off()
+      expect(getCurrentScope()).toBe(parentScope)
+    })
+  })
+
   it('should pause/resume EffectScope', async () => {
     const counter = reactive({ num: 0 })
     const fnSpy = vi.fn(() => counter.num)
index 80f42db6484e59fa783b8252b32d6f448251d321..9ca24c08857ad721472d0e34a8c50be8890507cf 100644 (file)
@@ -8,6 +8,10 @@ export class EffectScope {
    * @internal
    */
   private _active = true
+  /**
+   * @internal track `on` calls, allow `on` call multiple times
+   */
+  private _on = 0
   /**
    * @internal
    */
@@ -105,8 +109,10 @@ export class EffectScope {
    * @internal
    */
   on(): void {
-    this.prevScope = activeEffectScope
-    activeEffectScope = this
+    if (++this._on === 1) {
+      this.prevScope = activeEffectScope
+      activeEffectScope = this
+    }
   }
 
   /**
@@ -114,7 +120,10 @@ export class EffectScope {
    * @internal
    */
   off(): void {
-    activeEffectScope = this.prevScope
+    if (this._on > 0 && --this._on === 0) {
+      activeEffectScope = this.prevScope
+      this.prevScope = undefined
+    }
   }
 
   stop(fromParent?: boolean): void {