fix(runtime-core): fix v-on object kebab-case event emit matching

fix #3527
This commit is contained in:
Evan You 2021-04-01 19:47:58 -04:00
parent 995d76bd12
commit c1cd42e627
2 changed files with 60 additions and 8 deletions

View File

@ -1,7 +1,13 @@
// Note: emits and listener fallthrough is tested in // Note: emits and listener fallthrough is tested in
// ./rendererAttrsFallthrough.spec.ts. // ./rendererAttrsFallthrough.spec.ts.
import { render, defineComponent, h, nodeOps } from '@vue/runtime-test' import {
render,
defineComponent,
h,
nodeOps,
toHandlers
} from '@vue/runtime-test'
import { isEmitListener } from '../src/componentEmits' import { isEmitListener } from '../src/componentEmits'
describe('component: emit', () => { describe('component: emit', () => {
@ -28,7 +34,7 @@ describe('component: emit', () => {
expect(onBaz).toHaveBeenCalled() expect(onBaz).toHaveBeenCalled()
}) })
test('trigger camelize event', () => { test('trigger camelCase handler', () => {
const Foo = defineComponent({ const Foo = defineComponent({
render() {}, render() {},
created() { created() {
@ -43,7 +49,52 @@ describe('component: emit', () => {
}) })
render(h(Comp), nodeOps.createElement('div')) render(h(Comp), nodeOps.createElement('div'))
expect(fooSpy).toHaveBeenCalled() expect(fooSpy).toHaveBeenCalledTimes(1)
})
test('trigger kebab-case handler', () => {
const Foo = defineComponent({
render() {},
created() {
this.$emit('test-event')
}
})
const fooSpy = jest.fn()
const Comp = () =>
h(Foo, {
'onTest-event': fooSpy
})
render(h(Comp), nodeOps.createElement('div'))
expect(fooSpy).toHaveBeenCalledTimes(1)
})
// #3527
test('trigger mixed case handlers', () => {
const Foo = defineComponent({
render() {},
created() {
this.$emit('test-event')
this.$emit('testEvent')
}
})
const fooSpy = jest.fn()
const barSpy = jest.fn()
const Comp = () =>
// simulate v-on="obj" usage
h(
Foo,
toHandlers({
'test-event': fooSpy,
testEvent: barSpy
})
)
render(h(Comp), nodeOps.createElement('div'))
expect(fooSpy).toHaveBeenCalledTimes(1)
expect(fooSpy).toHaveBeenCalledTimes(1)
}) })
// for v-model:foo-bar usage in DOM templates // for v-model:foo-bar usage in DOM templates

View File

@ -114,14 +114,15 @@ export function emit(
} }
} }
// convert handler name to camelCase. See issue #2249 let handlerName
let handlerName = toHandlerKey(camelize(event)) let handler =
let handler = props[handlerName] props[(handlerName = toHandlerKey(event))] ||
// also try camelCase event handler (#2249)
props[(handlerName = toHandlerKey(camelize(event)))]
// for v-model update:xxx events, also trigger kebab-case equivalent // for v-model update:xxx events, also trigger kebab-case equivalent
// for props passed via kebab-case // for props passed via kebab-case
if (!handler && isModelListener) { if (!handler && isModelListener) {
handlerName = toHandlerKey(hyphenate(event)) handler = props[(handlerName = toHandlerKey(hyphenate(event)))]
handler = props[handlerName]
} }
if (handler) { if (handler) {