diff --git a/src/emit.ts b/src/emit.ts index 27e292534..74fd44c8e 100644 --- a/src/emit.ts +++ b/src/emit.ts @@ -48,7 +48,7 @@ function recordEvent( events: Events, vm: ComponentInternalInstance, event: string, - args: Events[number] + args: unknown[] ): void { // Functional component wrapper creates a parent component let wrapperVm = vm @@ -64,4 +64,16 @@ function recordEvent( // Record the event message sent by the emit events[cid][event].push(args) + + if (event.startsWith('update:')) { + if (args.length !== 1) { + throw new Error( + 'Two-way bound properties have to emit a single value. ' + + args.length + + ' values given.' + ) + } + + vm.props[event.slice('update:'.length)] = args[0] + } } diff --git a/tests/props.spec.ts b/tests/props.spec.ts index d2e543fd3..cff91719f 100644 --- a/tests/props.spec.ts +++ b/tests/props.spec.ts @@ -1,6 +1,7 @@ import { mount } from '../src' import WithProps from './components/WithProps.vue' import Hello from './components/Hello.vue' +import { defineComponent } from 'vue' describe('props', () => { it('returns a single prop applied to a component', () => { @@ -82,4 +83,32 @@ describe('props', () => { object: {} }) }) + + it('should return the updated props on 2 way binding', async () => { + const component = defineComponent({ + template: '', + props: { + modelValue: { + type: Number, + required: true + } + }, + emits: ['update:modelValue'], + setup(props, ctx) { + return { + increment: () => ctx.emit('update:modelValue', props.modelValue + 1) + } + } + }) + + const wrapper = mount(component, { + props: { + modelValue: 1 + } + }) + + expect(wrapper.props('modelValue')).toBe(1) + await wrapper.trigger('click') + expect(wrapper.props('modelValue')).toBe(2) + }) })