From 2837ce842856d51dfbb55e3fa4a36a352446fb54 Mon Sep 17 00:00:00 2001 From: Evan You Date: Sun, 26 Jan 2020 14:13:55 -0500 Subject: [PATCH] fix(v-model/emit): update:camelCase events should trigger kebab case equivalent close #656 --- .../runtime-core/__tests__/component.spec.ts | 26 +++++++++++++++++++ packages/runtime-core/src/component.ts | 9 +++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/packages/runtime-core/__tests__/component.spec.ts b/packages/runtime-core/__tests__/component.spec.ts index 848509af8c..bf9377e1b9 100644 --- a/packages/runtime-core/__tests__/component.spec.ts +++ b/packages/runtime-core/__tests__/component.spec.ts @@ -78,7 +78,9 @@ describe('renderer: component', () => { setup() { return () => h(Child, { + // emit triggering single handler onBar: () => 1, + // emit triggering multiple handlers onBaz: [() => Promise.resolve(2), () => Promise.resolve(3)] }) } @@ -86,8 +88,32 @@ describe('renderer: component', () => { render(h(App), nodeOps.createElement('div')) + // assert return values from emit expect(noMatchEmitResult).toMatchObject([]) expect(singleEmitResult).toMatchObject([1]) expect(await Promise.all(multiEmitResult)).toMatchObject([2, 3]) }) + + // for v-model:foo-bar usage in DOM templates + test('emit update:xxx events should trigger kebab-case equivalent', () => { + const Child = defineComponent({ + setup(_, { emit }) { + emit('update:fooBar', 1) + return () => h('div') + } + }) + + const handler = jest.fn() + const App = { + setup() { + return () => + h(Child, { + 'onUpdate:foo-bar': handler + }) + } + } + + render(h(App), nodeOps.createElement('div')) + expect(handler).toHaveBeenCalled() + }) }) diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index 9bfaf50b00..b46d10ab55 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -25,7 +25,8 @@ import { NO, makeMap, isPromise, - isArray + isArray, + hyphenate } from '@vue/shared' import { SuspenseBoundary } from './components/Suspense' import { CompilerOptions } from '@vue/compiler-core' @@ -221,7 +222,11 @@ export function defineComponentInstance( emit: (event, ...args): any[] => { const props = instance.vnode.props || EMPTY_OBJ - const handler = props[`on${event}`] || props[`on${capitalize(event)}`] + let handler = props[`on${event}`] || props[`on${capitalize(event)}`] + if (!handler && event.indexOf('update:') === 0) { + event = hyphenate(event) + handler = props[`on${event}`] || props[`on${capitalize(event)}`] + } if (handler) { const res = callWithAsyncErrorHandling( handler, -- 2.47.3