if (arg.type === NodeTypes.SIMPLE_EXPRESSION) {
if (arg.isStatic) {
const rawName = arg.content
- // for @vnode-xxx event listeners, auto convert it to camelCase
- const normalizedName = rawName.startsWith(`vnode`)
- ? capitalize(camelize(rawName))
- : capitalize(rawName)
+ // for all event listeners, auto convert it to camelCase. See issue #2249
+ const normalizedName = capitalize(camelize(rawName))
eventName = createSimpleExpression(`on${normalizedName}`, true, arg.loc)
} else {
eventName = createCompoundExpression([
expect(onBaz).toHaveBeenCalled()
})
+ test('trigger camelize event', () => {
+ const Foo = defineComponent({
+ render() {},
+ created() {
+ this.$emit('test-event')
+ }
+ })
+
+ const fooSpy = jest.fn()
+ const Comp = () =>
+ h(Foo, {
+ onTestEvent: fooSpy
+ })
+ render(h(Comp), nodeOps.createElement('div'))
+
+ expect(fooSpy).toHaveBeenCalled()
+ })
+
// for v-model:foo-bar usage in DOM templates
test('trigger hyphenated events for update:xxx events', () => {
const Foo = defineComponent({
capitalize,
hyphenate,
isFunction,
- extend
+ extend,
+ camelize
} from '@vue/shared'
import {
ComponentInternalInstance,
ComponentOptions,
- ConcreteComponent
+ ConcreteComponent,
+ formatComponentName
} from './component'
import { callWithAsyncErrorHandling, ErrorCodes } from './errorHandling'
import { warn } from './warning'
devtoolsComponentEmit(instance, event, args)
}
- let handlerName = `on${capitalize(event)}`
+ if (__DEV__) {
+ const lowerCaseEvent = event.toLowerCase()
+ if (lowerCaseEvent !== event && props[`on` + capitalize(lowerCaseEvent)]) {
+ warn(
+ `Event "${lowerCaseEvent}" is emitted in component ` +
+ `${formatComponentName(
+ instance,
+ instance.type
+ )} but the handler is registered for "${event}". ` +
+ `Note that HTML attributes are case-insensitive and you cannot use ` +
+ `v-on to listen to camelCase events when using in-DOM templates. ` +
+ `You should probably use "${hyphenate(event)}" instead of "${event}".`
+ )
+ }
+ }
+
+ // convert handler name to camelCase. See issue #2249
+ let handlerName = `on${capitalize(camelize(event))}`
let handler = props[handlerName]
// for v-model update:xxx events, also trigger kebab-case equivalent
// for props passed via kebab-case