diff --git a/packages/reactivity/__tests__/effectScope.spec.ts b/packages/reactivity/__tests__/effectScope.spec.ts index 537cac64c6b..debbdafb1e7 100644 --- a/packages/reactivity/__tests__/effectScope.spec.ts +++ b/packages/reactivity/__tests__/effectScope.spec.ts @@ -176,7 +176,7 @@ describe('reactivity/effect/scope', () => { expect('[Vue warn] cannot run an inactive effect scope.').toHaveBeenWarned() - expect(scope.effects.length).toBe(1) + expect(scope.effects.length).toBe(0) counter.num = 7 expect(dummy).toBe(0) @@ -358,5 +358,8 @@ describe('reactivity/effect/scope', () => { await nextTick() expect(watcherCalls).toBe(3) expect(cleanupCalls).toBe(1) + + expect(scope.effects.length).toBe(0) + expect(scope.cleanups.length).toBe(0) }) }) diff --git a/packages/reactivity/src/effectScope.ts b/packages/reactivity/src/effectScope.ts index 98e45fb5707..e045d30e89b 100644 --- a/packages/reactivity/src/effectScope.ts +++ b/packages/reactivity/src/effectScope.ts @@ -119,17 +119,24 @@ export class EffectScope { if (this._active) { this._active = false let i, l - for (i = 0, l = this.effects.length; i < l; i++) { - this.effects[i].stop() + const effects = this.effects.slice() + for (i = 0, l = effects.length; i < l; i++) { + effects[i].stop() } + this.effects.length = 0 + for (i = 0, l = this.cleanups.length; i < l; i++) { this.cleanups[i]() } + this.cleanups.length = 0 + if (this.scopes) { for (i = 0, l = this.scopes.length; i < l; i++) { this.scopes[i].stop(true) } + this.scopes.length = 0 } + // nested scope, dereference from parent to avoid memory leaks if (!this.detached && this.parent && !fromParent) { // optimized O(1) removal diff --git a/packages/runtime-core/__tests__/apiWatch.spec.ts b/packages/runtime-core/__tests__/apiWatch.spec.ts index 10a4fe659e0..7d2a1e73c08 100644 --- a/packages/runtime-core/__tests__/apiWatch.spec.ts +++ b/packages/runtime-core/__tests__/apiWatch.spec.ts @@ -25,7 +25,6 @@ import { } from '@vue/runtime-test' import { type DebuggerEvent, - EffectFlags, ITERATE_KEY, type Ref, type ShallowRef, @@ -1341,7 +1340,7 @@ describe('api: watch', () => { await nextTick() await nextTick() - expect(instance!.scope.effects[0].flags & EffectFlags.ACTIVE).toBeFalsy() + expect(instance!.scope.effects.length).toBe(0) }) test('this.$watch should pass `this.proxy` to watch source as the first argument ', () => {