Skip to content

Commit 0b39e46

Browse files
authored
fix(custom-elements): also dispatch hyphenated version of emitted events (#5378)
fix #5373
1 parent 192dcb6 commit 0b39e46

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

packages/runtime-dom/__tests__/customElement.spec.ts

+22-2
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,12 @@ describe('defineCustomElement', () => {
232232
emit('created')
233233
return () =>
234234
h('div', {
235-
onClick: () => emit('my-click', 1)
235+
onClick: () => {
236+
emit('my-click', 1)
237+
},
238+
onMousedown: () => {
239+
emit('myEvent', 1) // validate hypenization
240+
}
236241
})
237242
}
238243
})
@@ -252,11 +257,26 @@ describe('defineCustomElement', () => {
252257
const spy = jest.fn()
253258
e.addEventListener('my-click', spy)
254259
e.shadowRoot!.childNodes[0].dispatchEvent(new CustomEvent('click'))
255-
expect(spy).toHaveBeenCalled()
260+
expect(spy).toHaveBeenCalledTimes(1)
256261
expect(spy.mock.calls[0][0]).toMatchObject({
257262
detail: [1]
258263
})
259264
})
265+
266+
// #5373
267+
test('case transform for camelCase event', () => {
268+
container.innerHTML = `<my-el-emits></my-el-emits>`
269+
const e = container.childNodes[0] as VueElement
270+
const spy1 = jest.fn()
271+
e.addEventListener('myEvent', spy1)
272+
const spy2 = jest.fn()
273+
// emitting myEvent, but listening for my-event. This happens when
274+
// using the custom element in a Vue template
275+
e.addEventListener('my-event', spy2)
276+
e.shadowRoot!.childNodes[0].dispatchEvent(new CustomEvent('mousedown'))
277+
expect(spy1).toHaveBeenCalledTimes(1)
278+
expect(spy2).toHaveBeenCalledTimes(1)
279+
})
260280
})
261281

262282
describe('slots', () => {

packages/runtime-dom/src/apiCustomElement.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -351,15 +351,24 @@ export class VueElement extends BaseClass {
351351
}
352352
}
353353

354-
// intercept emit
355-
instance.emit = (event: string, ...args: any[]) => {
354+
const dispatch = (event: string, args: any[]) => {
356355
this.dispatchEvent(
357356
new CustomEvent(event, {
358357
detail: args
359358
})
360359
)
361360
}
362361

362+
// intercept emit
363+
instance.emit = (event: string, ...args: any[]) => {
364+
// dispatch both the raw and hyphenated versions of an event
365+
// to match Vue behavior
366+
dispatch(event, args)
367+
if (hyphenate(event) !== event) {
368+
dispatch(hyphenate(event), args)
369+
}
370+
}
371+
363372
// locate nearest Vue custom element parent for provide/inject
364373
let parent: Node | null = this
365374
while (

0 commit comments

Comments
 (0)