Skip to content

Commit 4bbb2b2

Browse files
committed
fix(runtime-core): fix component .once listener logic
1 parent 6d2a1cb commit 4bbb2b2

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

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

+24
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,30 @@ describe('component: emit', () => {
196196
expect(fn).toHaveBeenCalledTimes(1)
197197
})
198198

199+
test('.once with normal listener of the same name', () => {
200+
const Foo = defineComponent({
201+
render() {},
202+
emits: {
203+
foo: null
204+
},
205+
created() {
206+
this.$emit('foo')
207+
this.$emit('foo')
208+
}
209+
})
210+
const onFoo = jest.fn()
211+
const onFooOnce = jest.fn()
212+
render(
213+
h(Foo, {
214+
onFoo,
215+
onFooOnce
216+
}),
217+
nodeOps.createElement('div')
218+
)
219+
expect(onFoo).toHaveBeenCalledTimes(2)
220+
expect(onFooOnce).toHaveBeenCalledTimes(1)
221+
})
222+
199223
test('isEmitListener', () => {
200224
const options = { click: null }
201225
expect(isEmitListener(options, 'onClick')).toBe(true)

packages/runtime-core/src/componentEmits.ts

+13-5
Original file line numberDiff line numberDiff line change
@@ -105,17 +105,25 @@ export function emit(
105105
handlerName = toHandlerKey(hyphenate(event))
106106
handler = props[handlerName]
107107
}
108-
if (!handler) {
109-
handler = props[handlerName + `Once`]
108+
109+
if (handler) {
110+
callWithAsyncErrorHandling(
111+
handler,
112+
instance,
113+
ErrorCodes.COMPONENT_EVENT_HANDLER,
114+
args
115+
)
116+
}
117+
118+
const onceHandler = props[handlerName + `Once`]
119+
if (onceHandler) {
110120
if (!instance.emitted) {
111121
;(instance.emitted = {} as Record<string, boolean>)[handlerName] = true
112122
} else if (instance.emitted[handlerName]) {
113123
return
114124
}
115-
}
116-
if (handler) {
117125
callWithAsyncErrorHandling(
118-
handler,
126+
onceHandler,
119127
instance,
120128
ErrorCodes.COMPONENT_EVENT_HANDLER,
121129
args

0 commit comments

Comments
 (0)