mirror of https://github.com/vuejs/core.git
fix(reactivity): ensure multiple effectScope on() and off() calls maintains correct active scope
close #12631
close #12632
This is a combination of changes from both 8dec243
and #12641
This commit is contained in:
parent
e8e842241a
commit
22dcbf3e20
|
@ -8,6 +8,10 @@ export class EffectScope {
|
|||
* @internal
|
||||
*/
|
||||
private _active = true
|
||||
/**
|
||||
* @internal track `on` calls, allow `on` call multiple times
|
||||
*/
|
||||
private _on = 0
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
@ -99,20 +103,27 @@ export class EffectScope {
|
|||
}
|
||||
}
|
||||
|
||||
prevScope: EffectScope | undefined
|
||||
/**
|
||||
* This should only be called on non-detached scopes
|
||||
* @internal
|
||||
*/
|
||||
on(): void {
|
||||
if (++this._on === 1) {
|
||||
this.prevScope = activeEffectScope
|
||||
activeEffectScope = this
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This should only be called on non-detached scopes
|
||||
* @internal
|
||||
*/
|
||||
off(): void {
|
||||
activeEffectScope = this.parent
|
||||
if (this._on > 0 && --this._on === 0) {
|
||||
activeEffectScope = this.prevScope
|
||||
this.prevScope = undefined
|
||||
}
|
||||
}
|
||||
|
||||
stop(fromParent?: boolean): void {
|
||||
|
|
|
@ -31,6 +31,7 @@ import {
|
|||
TrackOpTypes,
|
||||
TriggerOpTypes,
|
||||
effectScope,
|
||||
onScopeDispose,
|
||||
shallowReactive,
|
||||
shallowRef,
|
||||
toRef,
|
||||
|
@ -1982,4 +1983,31 @@ describe('api: watch', () => {
|
|||
expect(spy1).toHaveBeenCalled()
|
||||
expect(spy2).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
// #12631
|
||||
test('this.$watch w/ onScopeDispose', () => {
|
||||
const onCleanup = vi.fn()
|
||||
const toggle = ref(true)
|
||||
|
||||
const Comp = defineComponent({
|
||||
render() {},
|
||||
created(this: any) {
|
||||
this.$watch(
|
||||
() => 1,
|
||||
function () {},
|
||||
)
|
||||
onScopeDispose(onCleanup)
|
||||
},
|
||||
})
|
||||
|
||||
const App = defineComponent({
|
||||
render() {
|
||||
return toggle.value ? h(Comp) : null
|
||||
},
|
||||
})
|
||||
|
||||
const root = nodeOps.createElement('div')
|
||||
createApp(App).mount(root)
|
||||
expect(onCleanup).toBeCalledTimes(0)
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue