fix(runtime-core): use consistent camelCase event casing for render functions (#2278)
close #2249
This commit is contained in:
parent
390589ec6d
commit
62f26173ba
@ -42,10 +42,8 @@ export const transformOn: DirectiveTransform = (
|
||||
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([
|
||||
|
@ -28,6 +28,24 @@ describe('component: emit', () => {
|
||||
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({
|
||||
|
@ -6,12 +6,14 @@ import {
|
||||
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'
|
||||
@ -78,7 +80,24 @@ export function emit(
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user