setup() {
return () =>
h(Child, {
+ // emit triggering single handler
onBar: () => 1,
+ // emit triggering multiple handlers
onBaz: [() => Promise.resolve(2), () => Promise.resolve(3)]
})
}
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()
+ })
})
NO,
makeMap,
isPromise,
- isArray
+ isArray,
+ hyphenate
} from '@vue/shared'
import { SuspenseBoundary } from './components/Suspense'
import { CompilerOptions } from '@vue/compiler-core'
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,