fix(custom-elements): also dispatch hyphenated version of emitted events (#5378)

fix #5373
This commit is contained in:
Thorsten Lünborg 2022-11-11 05:01:10 +01:00 committed by GitHub
parent 192dcb648c
commit 0b39e46192
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 4 deletions

View File

@ -232,7 +232,12 @@ describe('defineCustomElement', () => {
emit('created') emit('created')
return () => return () =>
h('div', { h('div', {
onClick: () => emit('my-click', 1) onClick: () => {
emit('my-click', 1)
},
onMousedown: () => {
emit('myEvent', 1) // validate hypenization
}
}) })
} }
}) })
@ -252,11 +257,26 @@ describe('defineCustomElement', () => {
const spy = jest.fn() const spy = jest.fn()
e.addEventListener('my-click', spy) e.addEventListener('my-click', spy)
e.shadowRoot!.childNodes[0].dispatchEvent(new CustomEvent('click')) e.shadowRoot!.childNodes[0].dispatchEvent(new CustomEvent('click'))
expect(spy).toHaveBeenCalled() expect(spy).toHaveBeenCalledTimes(1)
expect(spy.mock.calls[0][0]).toMatchObject({ expect(spy.mock.calls[0][0]).toMatchObject({
detail: [1] detail: [1]
}) })
}) })
// #5373
test('case transform for camelCase event', () => {
container.innerHTML = `<my-el-emits></my-el-emits>`
const e = container.childNodes[0] as VueElement
const spy1 = jest.fn()
e.addEventListener('myEvent', spy1)
const spy2 = jest.fn()
// emitting myEvent, but listening for my-event. This happens when
// using the custom element in a Vue template
e.addEventListener('my-event', spy2)
e.shadowRoot!.childNodes[0].dispatchEvent(new CustomEvent('mousedown'))
expect(spy1).toHaveBeenCalledTimes(1)
expect(spy2).toHaveBeenCalledTimes(1)
})
}) })
describe('slots', () => { describe('slots', () => {

View File

@ -351,8 +351,7 @@ export class VueElement extends BaseClass {
} }
} }
// intercept emit const dispatch = (event: string, args: any[]) => {
instance.emit = (event: string, ...args: any[]) => {
this.dispatchEvent( this.dispatchEvent(
new CustomEvent(event, { new CustomEvent(event, {
detail: args detail: args
@ -360,6 +359,16 @@ export class VueElement extends BaseClass {
) )
} }
// intercept emit
instance.emit = (event: string, ...args: any[]) => {
// dispatch both the raw and hyphenated versions of an event
// to match Vue behavior
dispatch(event, args)
if (hyphenate(event) !== event) {
dispatch(hyphenate(event), args)
}
}
// locate nearest Vue custom element parent for provide/inject // locate nearest Vue custom element parent for provide/inject
let parent: Node | null = this let parent: Node | null = this
while ( while (