From 3056e9b3dcb1ab0bd18227c6fa7bf283f98f6ef6 Mon Sep 17 00:00:00 2001 From: Evan You Date: Mon, 19 Jul 2021 17:46:04 -0400 Subject: [PATCH] fix(v-model): properly detect input type=number fix #3813 --- .../__tests__/directives/vModel.spec.ts | 31 +++++++++++++++++++ packages/runtime-dom/src/directives/vModel.ts | 3 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/packages/runtime-dom/__tests__/directives/vModel.spec.ts b/packages/runtime-dom/__tests__/directives/vModel.spec.ts index 52b5e301..503b137c 100644 --- a/packages/runtime-dom/__tests__/directives/vModel.spec.ts +++ b/packages/runtime-dom/__tests__/directives/vModel.spec.ts @@ -70,6 +70,37 @@ describe('vModel', () => { expect(input.value).toEqual('') }) + it('should work with number input', async () => { + const component = defineComponent({ + data() { + return { value: null } + }, + render() { + return [ + withVModel( + h('input', { + type: 'number', + 'onUpdate:modelValue': setValue.bind(this) + }), + this.value + ) + ] + } + }) + render(h(component), root) + + const input = root.querySelector('input')! + const data = root._vnode.component.data + expect(input.value).toEqual('') + expect(input.type).toEqual('number') + + input.value = 1 + triggerEvent('input', input) + await nextTick() + expect(typeof data.value).toEqual('number') + expect(data.value).toEqual(1) + }) + it('should work with multiple listeners', async () => { const spy = jest.fn() const component = defineComponent({ diff --git a/packages/runtime-dom/src/directives/vModel.ts b/packages/runtime-dom/src/directives/vModel.ts index d721e2f3..42960eca 100644 --- a/packages/runtime-dom/src/directives/vModel.ts +++ b/packages/runtime-dom/src/directives/vModel.ts @@ -49,7 +49,8 @@ export const vModelText: ModelDirective< > = { created(el, { modifiers: { lazy, trim, number } }, vnode) { el._assign = getModelAssigner(vnode) - const castToNumber = number || el.type === 'number' + const castToNumber = + number || (vnode.props && vnode.props.type === 'number') addEventListener(el, lazy ? 'change' : 'input', e => { if ((e.target as any).composing) return let domValue: string | number = el.value