mirror of https://github.com/vuejs/core.git
fix(runtime-core): ensure tracking is paused when emit() calls handler so it can safely be called in effects
fix: #6669
This commit is contained in:
parent
8772a01a92
commit
1c02e5a9c2
|
@ -7,7 +7,9 @@ import {
|
|||
h,
|
||||
nodeOps,
|
||||
toHandlers,
|
||||
nextTick
|
||||
nextTick,
|
||||
ref,
|
||||
watchEffect
|
||||
} from '@vue/runtime-test'
|
||||
import { isEmitListener } from '../src/componentEmits'
|
||||
|
||||
|
@ -431,4 +433,36 @@ describe('component: emit', () => {
|
|||
await nextTick()
|
||||
expect(fn).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test('should not track during listener execution', async () => {
|
||||
const counter = ref(0)
|
||||
const Comp = defineComponent({
|
||||
emits: ['interaction'],
|
||||
setup(props, { emit }) {
|
||||
const doEmit = ref(true)
|
||||
watchEffect(() => {
|
||||
if (doEmit.value) emit('interaction')
|
||||
})
|
||||
return () => h('div')
|
||||
}
|
||||
})
|
||||
const el = nodeOps.createElement('div')
|
||||
render(
|
||||
h(Comp, {
|
||||
onInteraction: async () => {
|
||||
if (counter.value < 5) {
|
||||
await nextTick()
|
||||
counter.value++
|
||||
}
|
||||
}
|
||||
}),
|
||||
el
|
||||
)
|
||||
|
||||
await nextTick()
|
||||
await nextTick()
|
||||
await nextTick()
|
||||
|
||||
expect(counter.value).toBe(1)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -27,6 +27,7 @@ import {
|
|||
compatModelEventPrefix,
|
||||
compatModelEmit
|
||||
} from './compat/componentVModel'
|
||||
import { pauseTracking, resetTracking } from '@vue/reactivity'
|
||||
|
||||
export type ObjectEmitsOptions = Record<
|
||||
string,
|
||||
|
@ -161,12 +162,14 @@ export function emit(
|
|||
}
|
||||
|
||||
if (handler) {
|
||||
pauseTracking()
|
||||
callWithAsyncErrorHandling(
|
||||
handler,
|
||||
instance,
|
||||
ErrorCodes.COMPONENT_EVENT_HANDLER,
|
||||
args
|
||||
)
|
||||
resetTracking()
|
||||
}
|
||||
|
||||
const onceHandler = props[handlerName + `Once`]
|
||||
|
|
Loading…
Reference in New Issue