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(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,
|
||||
ReactiveFlags,
|
||||
type Ref,
|
||||
getCurrentScope,
|
||||
isReactive,
|
||||
isRef,
|
||||
isShallow,
|
||||
|
@ -394,10 +395,11 @@ function doWatch(
|
|||
|
||||
const effect = new ReactiveEffect(getter, NOOP, scheduler)
|
||||
|
||||
const scope = getCurrentScope()
|
||||
const unwatch = () => {
|
||||
effect.stop()
|
||||
if (instance && instance.scope) {
|
||||
remove(instance.scope.effects!, effect)
|
||||
if (scope) {
|
||||
remove(scope.effects, effect)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue