mirror of
https://github.com/vuejs/vue.git
synced 2024-11-21 20:28:54 +00:00
fix(lifecycle): scope might changed when call hook (#13070)
This commit is contained in:
parent
1399ee6aa0
commit
74ca5a13ba
@ -18,6 +18,7 @@ import {
|
|||||||
invokeWithErrorHandling
|
invokeWithErrorHandling
|
||||||
} from '../util/index'
|
} from '../util/index'
|
||||||
import { currentInstance, setCurrentInstance } from 'v3/currentInstance'
|
import { currentInstance, setCurrentInstance } from 'v3/currentInstance'
|
||||||
|
import { getCurrentScope } from 'v3/reactivity/effectScope'
|
||||||
import { syncSetupProxy } from 'v3/apiSetup'
|
import { syncSetupProxy } from 'v3/apiSetup'
|
||||||
|
|
||||||
export let activeInstance: any = null
|
export let activeInstance: any = null
|
||||||
@ -398,7 +399,8 @@ export function callHook(
|
|||||||
) {
|
) {
|
||||||
// #7573 disable dep collection when invoking lifecycle hooks
|
// #7573 disable dep collection when invoking lifecycle hooks
|
||||||
pushTarget()
|
pushTarget()
|
||||||
const prev = currentInstance
|
const prevInst = currentInstance
|
||||||
|
const prevScope = getCurrentScope()
|
||||||
setContext && setCurrentInstance(vm)
|
setContext && setCurrentInstance(vm)
|
||||||
const handlers = vm.$options[hook]
|
const handlers = vm.$options[hook]
|
||||||
const info = `${hook} hook`
|
const info = `${hook} hook`
|
||||||
@ -410,6 +412,10 @@ export function callHook(
|
|||||||
if (vm._hasHookEvent) {
|
if (vm._hasHookEvent) {
|
||||||
vm.$emit('hook:' + hook)
|
vm.$emit('hook:' + hook)
|
||||||
}
|
}
|
||||||
setContext && setCurrentInstance(prev)
|
if (setContext) {
|
||||||
|
setCurrentInstance(prevInst)
|
||||||
|
prevScope && prevScope.on()
|
||||||
|
}
|
||||||
|
|
||||||
popTarget()
|
popTarget()
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
import { nextTick } from 'core/util'
|
import { nextTick } from 'core/util'
|
||||||
import {
|
import {
|
||||||
watch,
|
watch,
|
||||||
@ -290,4 +291,28 @@ describe('reactivity/effectScope', () => {
|
|||||||
expect(getCurrentScope()).toBe(parentScope)
|
expect(getCurrentScope()).toBe(parentScope)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('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)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user