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.type === NodeTypes.SIMPLE_EXPRESSION) {
|
||||||
if (arg.isStatic) {
|
if (arg.isStatic) {
|
||||||
const rawName = arg.content
|
const rawName = arg.content
|
||||||
// for @vnode-xxx event listeners, auto convert it to camelCase
|
// for all event listeners, auto convert it to camelCase. See issue #2249
|
||||||
const normalizedName = rawName.startsWith(`vnode`)
|
const normalizedName = capitalize(camelize(rawName))
|
||||||
? capitalize(camelize(rawName))
|
|
||||||
: capitalize(rawName)
|
|
||||||
eventName = createSimpleExpression(`on${normalizedName}`, true, arg.loc)
|
eventName = createSimpleExpression(`on${normalizedName}`, true, arg.loc)
|
||||||
} else {
|
} else {
|
||||||
eventName = createCompoundExpression([
|
eventName = createCompoundExpression([
|
||||||
|
@ -28,6 +28,24 @@ describe('component: emit', () => {
|
|||||||
expect(onBaz).toHaveBeenCalled()
|
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
|
// for v-model:foo-bar usage in DOM templates
|
||||||
test('trigger hyphenated events for update:xxx events', () => {
|
test('trigger hyphenated events for update:xxx events', () => {
|
||||||
const Foo = defineComponent({
|
const Foo = defineComponent({
|
||||||
|
@ -6,12 +6,14 @@ import {
|
|||||||
capitalize,
|
capitalize,
|
||||||
hyphenate,
|
hyphenate,
|
||||||
isFunction,
|
isFunction,
|
||||||
extend
|
extend,
|
||||||
|
camelize
|
||||||
} from '@vue/shared'
|
} from '@vue/shared'
|
||||||
import {
|
import {
|
||||||
ComponentInternalInstance,
|
ComponentInternalInstance,
|
||||||
ComponentOptions,
|
ComponentOptions,
|
||||||
ConcreteComponent
|
ConcreteComponent,
|
||||||
|
formatComponentName
|
||||||
} from './component'
|
} from './component'
|
||||||
import { callWithAsyncErrorHandling, ErrorCodes } from './errorHandling'
|
import { callWithAsyncErrorHandling, ErrorCodes } from './errorHandling'
|
||||||
import { warn } from './warning'
|
import { warn } from './warning'
|
||||||
@ -78,7 +80,24 @@ export function emit(
|
|||||||
devtoolsComponentEmit(instance, event, args)
|
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]
|
let handler = props[handlerName]
|
||||||
// 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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user