mirror of https://github.com/vuejs/core.git
fix(watch): cleanup watcher effect from scope when manually stopped (#9978)
This commit is contained in:
parent
f70f7ca9ae
commit
d2d89551bb
|
@ -1443,4 +1443,35 @@ describe('api: watch', () => {
|
||||||
expect(spy1).toHaveBeenCalledTimes(1)
|
expect(spy1).toHaveBeenCalledTimes(1)
|
||||||
expect(spy2).toHaveBeenCalledTimes(1)
|
expect(spy2).toHaveBeenCalledTimes(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("effect should be removed from scope's effects after it is stopped", () => {
|
||||||
|
const num = ref(0)
|
||||||
|
let unwatch: () => void
|
||||||
|
|
||||||
|
let instance: ComponentInternalInstance
|
||||||
|
const Comp = {
|
||||||
|
setup() {
|
||||||
|
instance = getCurrentInstance()!
|
||||||
|
unwatch = watch(num, () => {
|
||||||
|
console.log(num.value)
|
||||||
|
})
|
||||||
|
return () => null
|
||||||
|
},
|
||||||
|
}
|
||||||
|
const root = nodeOps.createElement('div')
|
||||||
|
createApp(Comp).mount(root)
|
||||||
|
expect(instance!.scope.effects.length).toBe(2)
|
||||||
|
unwatch!()
|
||||||
|
expect(instance!.scope.effects.length).toBe(1)
|
||||||
|
|
||||||
|
const scope = effectScope()
|
||||||
|
scope.run(() => {
|
||||||
|
unwatch = watch(num, () => {
|
||||||
|
console.log(num.value)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
expect(scope.effects.length).toBe(1)
|
||||||
|
unwatch!()
|
||||||
|
expect(scope.effects.length).toBe(0)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -5,6 +5,7 @@ import {
|
||||||
ReactiveEffect,
|
ReactiveEffect,
|
||||||
ReactiveFlags,
|
ReactiveFlags,
|
||||||
type Ref,
|
type Ref,
|
||||||
|
getCurrentScope,
|
||||||
isReactive,
|
isReactive,
|
||||||
isRef,
|
isRef,
|
||||||
isShallow,
|
isShallow,
|
||||||
|
@ -394,10 +395,11 @@ function doWatch(
|
||||||
|
|
||||||
const effect = new ReactiveEffect(getter, NOOP, scheduler)
|
const effect = new ReactiveEffect(getter, NOOP, scheduler)
|
||||||
|
|
||||||
|
const scope = getCurrentScope()
|
||||||
const unwatch = () => {
|
const unwatch = () => {
|
||||||
effect.stop()
|
effect.stop()
|
||||||
if (instance && instance.scope) {
|
if (scope) {
|
||||||
remove(instance.scope.effects!, effect)
|
remove(scope.effects, effect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue