mirror of https://github.com/vuejs/core.git
fix(reactiivty): avoid unnecessary watcher effect removal from inactive scope
close #5783 close #5806
This commit is contained in:
parent
e9f3e6b546
commit
21932840ea
|
@ -322,4 +322,41 @@ describe('reactivity/effect/scope', () => {
|
|||
scope.resume()
|
||||
expect(fnSpy).toHaveBeenCalledTimes(3)
|
||||
})
|
||||
|
||||
test('removing a watcher while stopping its effectScope', async () => {
|
||||
const count = ref(0)
|
||||
const scope = effectScope()
|
||||
let watcherCalls = 0
|
||||
let cleanupCalls = 0
|
||||
|
||||
scope.run(() => {
|
||||
const stop1 = watch(count, () => {
|
||||
watcherCalls++
|
||||
})
|
||||
watch(count, (val, old, onCleanup) => {
|
||||
watcherCalls++
|
||||
onCleanup(() => {
|
||||
cleanupCalls++
|
||||
stop1()
|
||||
})
|
||||
})
|
||||
watch(count, () => {
|
||||
watcherCalls++
|
||||
})
|
||||
})
|
||||
|
||||
expect(watcherCalls).toBe(0)
|
||||
expect(cleanupCalls).toBe(0)
|
||||
|
||||
count.value++
|
||||
await nextTick()
|
||||
expect(watcherCalls).toBe(3)
|
||||
expect(cleanupCalls).toBe(0)
|
||||
|
||||
scope.stop()
|
||||
count.value++
|
||||
await nextTick()
|
||||
expect(watcherCalls).toBe(3)
|
||||
expect(cleanupCalls).toBe(1)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -117,6 +117,7 @@ export class EffectScope {
|
|||
|
||||
stop(fromParent?: boolean): void {
|
||||
if (this._active) {
|
||||
this._active = false
|
||||
let i, l
|
||||
for (i = 0, l = this.effects.length; i < l; i++) {
|
||||
this.effects[i].stop()
|
||||
|
@ -139,7 +140,6 @@ export class EffectScope {
|
|||
}
|
||||
}
|
||||
this.parent = undefined
|
||||
this._active = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -213,7 +213,7 @@ export function watch(
|
|||
const scope = getCurrentScope()
|
||||
const watchHandle: WatchHandle = () => {
|
||||
effect.stop()
|
||||
if (scope) {
|
||||
if (scope && scope.active) {
|
||||
remove(scope.effects, effect)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue