mirror of https://github.com/vuejs/core.git
fix(reactivity): release nested effects/scopes on effect scope stop (#12373)
close #12370
This commit is contained in:
parent
21932840ea
commit
bee2f5ee62
|
@ -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)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ', () => {
|
||||
|
|
Loading…
Reference in New Issue