Skip to content

Commit

Permalink
fix(lifecycle): scope might changed when call hook
Browse files Browse the repository at this point in the history
  • Loading branch information
gcaaa31928 committed Aug 23, 2023
1 parent 49b6bd4 commit f40e9dc
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
10 changes: 8 additions & 2 deletions src/core/instance/lifecycle.ts
Expand Up @@ -6,6 +6,7 @@ import { updateComponentListeners } from './events'
import { resolveSlots } from './render-helpers/resolve-slots'
import { toggleObserving } from '../observer/index'
import { pushTarget, popTarget } from '../observer/dep'
import { getCurrentScope } from '../../v3/reactivity/effectScope'
import type { Component } from 'types/component'
import type { MountedComponentVNode } from 'types/vnode'

Expand Down Expand Up @@ -398,7 +399,8 @@ export function callHook(
) {
// #7573 disable dep collection when invoking lifecycle hooks
pushTarget()
const prev = currentInstance
const prevInst = currentInstance
const prevScope = getCurrentScope()
setContext && setCurrentInstance(vm)
const handlers = vm.$options[hook]
const info = `${hook} hook`
Expand All @@ -410,6 +412,10 @@ export function callHook(
if (vm._hasHookEvent) {
vm.$emit('hook:' + hook)
}
setContext && setCurrentInstance(prev)
if (setContext) {
setCurrentInstance(prevInst)
prevScope?.on()
}

popTarget()
}
25 changes: 25 additions & 0 deletions test/unit/features/v3/reactivity/effectScope.spec.ts
@@ -1,3 +1,4 @@
import Vue from 'vue'
import { nextTick } from 'core/util'
import {
watch,
Expand Down Expand Up @@ -290,4 +291,28 @@ describe('reactivity/effectScope', () => {
expect(getCurrentScope()).toBe(parentScope)
})
})

it('test scope should not break currentScope when component call hooks', () => {
const scope = new EffectScope()
const vm = new Vue({
template: `
<div>
<div v-if="show" />
</div>
`,
data() {
return {
show: false
}
},
}).$mount()

scope.run(() => {
// call renderTriggered hook here
vm.show = true;
// this effect should be collected by scope not the component scope
effect(() => {})
})
expect(scope.effects.length).toBe(1)
});
})

0 comments on commit f40e9dc

Please sign in to comment.