* @internal
*/
private _active = true
+ /**
+ * @internal track `on` calls, allow `on` call multiple times
+ */
+ private _on = 0
/**
* @internal
*/
}
}
+ prevScope: EffectScope | undefined
/**
* This should only be called on non-detached scopes
* @internal
*/
on(): void {
- activeEffectScope = this
+ if (++this._on === 1) {
+ this.prevScope = activeEffectScope
+ activeEffectScope = this
+ }
}
/**
* @internal
*/
off(): void {
- activeEffectScope = this.parent
+ if (this._on > 0 && --this._on === 0) {
+ activeEffectScope = this.prevScope
+ this.prevScope = undefined
+ }
}
stop(fromParent?: boolean): void {
TrackOpTypes,
TriggerOpTypes,
effectScope,
+ onScopeDispose,
shallowReactive,
shallowRef,
toRef,
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)
+ })
})