Skip to content

Commit 74ca5a1

Browse files
authored
fix(lifecycle): scope might changed when call hook (#13070)
1 parent 1399ee6 commit 74ca5a1

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

src/core/instance/lifecycle.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
invokeWithErrorHandling
1919
} from '../util/index'
2020
import { currentInstance, setCurrentInstance } from 'v3/currentInstance'
21+
import { getCurrentScope } from 'v3/reactivity/effectScope'
2122
import { syncSetupProxy } from 'v3/apiSetup'
2223

2324
export let activeInstance: any = null
@@ -398,7 +399,8 @@ export function callHook(
398399
) {
399400
// #7573 disable dep collection when invoking lifecycle hooks
400401
pushTarget()
401-
const prev = currentInstance
402+
const prevInst = currentInstance
403+
const prevScope = getCurrentScope()
402404
setContext && setCurrentInstance(vm)
403405
const handlers = vm.$options[hook]
404406
const info = `${hook} hook`
@@ -410,6 +412,10 @@ export function callHook(
410412
if (vm._hasHookEvent) {
411413
vm.$emit('hook:' + hook)
412414
}
413-
setContext && setCurrentInstance(prev)
415+
if (setContext) {
416+
setCurrentInstance(prevInst)
417+
prevScope && prevScope.on()
418+
}
419+
414420
popTarget()
415421
}

test/unit/features/v3/reactivity/effectScope.spec.ts

+25
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import Vue from 'vue'
12
import { nextTick } from 'core/util'
23
import {
34
watch,
@@ -290,4 +291,28 @@ describe('reactivity/effectScope', () => {
290291
expect(getCurrentScope()).toBe(parentScope)
291292
})
292293
})
294+
295+
it('scope should not break currentScope when component call hooks', () => {
296+
const scope = new EffectScope()
297+
const vm = new Vue({
298+
template: `
299+
<div>
300+
<div v-if="show" />
301+
</div>
302+
`,
303+
data() {
304+
return {
305+
show: false
306+
}
307+
}
308+
}).$mount()
309+
310+
scope.run(() => {
311+
// call renderTriggered hook here
312+
vm.show = true
313+
// this effect should be collected by scope not the component scope
314+
effect(() => {})
315+
})
316+
expect(scope.effects.length).toBe(1)
317+
})
293318
})

0 commit comments

Comments
 (0)