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,
|
h,
|
||||||
nodeOps,
|
nodeOps,
|
||||||
toHandlers,
|
toHandlers,
|
||||||
nextTick
|
nextTick,
|
||||||
|
ref,
|
||||||
|
watchEffect
|
||||||
} from '@vue/runtime-test'
|
} from '@vue/runtime-test'
|
||||||
import { isEmitListener } from '../src/componentEmits'
|
import { isEmitListener } from '../src/componentEmits'
|
||||||
|
|
||||||
|
@ -431,4 +433,36 @@ describe('component: emit', () => {
|
||||||
await nextTick()
|
await nextTick()
|
||||||
expect(fn).not.toHaveBeenCalled()
|
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,
|
compatModelEventPrefix,
|
||||||
compatModelEmit
|
compatModelEmit
|
||||||
} from './compat/componentVModel'
|
} from './compat/componentVModel'
|
||||||
|
import { pauseTracking, resetTracking } from '@vue/reactivity'
|
||||||
|
|
||||||
export type ObjectEmitsOptions = Record<
|
export type ObjectEmitsOptions = Record<
|
||||||
string,
|
string,
|
||||||
|
@ -161,12 +162,14 @@ export function emit(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handler) {
|
if (handler) {
|
||||||
|
pauseTracking()
|
||||||
callWithAsyncErrorHandling(
|
callWithAsyncErrorHandling(
|
||||||
handler,
|
handler,
|
||||||
instance,
|
instance,
|
||||||
ErrorCodes.COMPONENT_EVENT_HANDLER,
|
ErrorCodes.COMPONENT_EVENT_HANDLER,
|
||||||
args
|
args
|
||||||
)
|
)
|
||||||
|
resetTracking()
|
||||||
}
|
}
|
||||||
|
|
||||||
const onceHandler = props[handlerName + `Once`]
|
const onceHandler = props[handlerName + `Once`]
|
||||||
|
|
Loading…
Reference in New Issue