Skip to content

Commit 09f17b4

Browse files
committed
fix: ensure tracking is paused when emit() calls handler so it can safely be called in effects
fix: #6669
1 parent 8772a01 commit 09f17b4

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

packages/runtime-core/__tests__/componentEmits.spec.ts

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import {
77
h,
88
nodeOps,
99
toHandlers,
10-
nextTick
10+
nextTick,
11+
ref,
12+
watchEffect
1113
} from '@vue/runtime-test'
1214
import { isEmitListener } from '../src/componentEmits'
1315

@@ -431,4 +433,36 @@ describe('component: emit', () => {
431433
await nextTick()
432434
expect(fn).not.toHaveBeenCalled()
433435
})
436+
437+
test('should not track during listener execution', async () => {
438+
const counter = ref(0)
439+
const Comp = defineComponent({
440+
emits: ['interaction'],
441+
setup(props, { emit }) {
442+
const doEmit = ref(true)
443+
watchEffect(() => {
444+
if (doEmit.value) emit('interaction')
445+
})
446+
return () => h('div')
447+
}
448+
})
449+
const el = nodeOps.createElement('div')
450+
render(
451+
h(Comp, {
452+
onInteraction: async () => {
453+
if (counter.value < 5) {
454+
await nextTick()
455+
counter.value++
456+
}
457+
}
458+
}),
459+
el
460+
)
461+
462+
await nextTick()
463+
await nextTick()
464+
await nextTick()
465+
466+
expect(counter.value).toBe(1)
467+
})
434468
})

packages/runtime-core/src/componentEmits.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
compatModelEventPrefix,
2828
compatModelEmit
2929
} from './compat/componentVModel'
30+
import { pauseTracking, resetTracking } from '@vue/reactivity'
3031

3132
export type ObjectEmitsOptions = Record<
3233
string,
@@ -161,12 +162,14 @@ export function emit(
161162
}
162163

163164
if (handler) {
165+
pauseTracking()
164166
callWithAsyncErrorHandling(
165167
handler,
166168
instance,
167169
ErrorCodes.COMPONENT_EVENT_HANDLER,
168170
args
169171
)
172+
resetTracking()
170173
}
171174

172175
const onceHandler = props[handlerName + `Once`]

0 commit comments

Comments
 (0)