From: 小刘(liulinboyi) <814921718@qq.com> Date: Thu, 12 May 2022 23:52:16 +0000 (+0800) Subject: fix(v-model): fix case where .trim and .number modifiers are used together (#5842) X-Git-Tag: v3.2.34-beta.1~31 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=71066b5afed7d3707b8ec9a6313dbdbd1adad45e;p=thirdparty%2Fvuejs%2Fcore.git fix(v-model): fix case where .trim and .number modifiers are used together (#5842) fix #5839 --- diff --git a/packages/runtime-core/__tests__/componentEmits.spec.ts b/packages/runtime-core/__tests__/componentEmits.spec.ts index 053d87140e..f22be2de0c 100644 --- a/packages/runtime-core/__tests__/componentEmits.spec.ts +++ b/packages/runtime-core/__tests__/componentEmits.spec.ts @@ -355,6 +355,37 @@ describe('component: emit', () => { expect(fn2).toHaveBeenCalledWith('two') }) + test('.trim and .number modifiers should work with v-model on component', () => { + const Foo = defineComponent({ + render() {}, + created() { + this.$emit('update:modelValue', ' +01.2 ') + this.$emit('update:foo', ' 1 ') + } + }) + + const fn1 = jest.fn() + const fn2 = jest.fn() + + const Comp = () => + h(Foo, { + modelValue: null, + modelModifiers: { trim: true, number: true }, + 'onUpdate:modelValue': fn1, + + foo: null, + fooModifiers: { trim: true, number: true }, + 'onUpdate:foo': fn2 + }) + + render(h(Comp), nodeOps.createElement('div')) + + expect(fn1).toHaveBeenCalledTimes(1) + expect(fn1).toHaveBeenCalledWith(1.2) + expect(fn2).toHaveBeenCalledTimes(1) + expect(fn2).toHaveBeenCalledWith(1) + }) + test('isEmitListener', () => { const options = { click: null, diff --git a/packages/runtime-core/src/componentEmits.ts b/packages/runtime-core/src/componentEmits.ts index 3983e5885b..68393c80b3 100644 --- a/packages/runtime-core/src/componentEmits.ts +++ b/packages/runtime-core/src/componentEmits.ts @@ -122,7 +122,8 @@ export function emit( const { number, trim } = props[modifiersKey] || EMPTY_OBJ if (trim) { args = rawArgs.map(a => a.trim()) - } else if (number) { + } + if (number) { args = rawArgs.map(toNumber) } } diff --git a/packages/runtime-dom/__tests__/directives/vModel.spec.ts b/packages/runtime-dom/__tests__/directives/vModel.spec.ts index a192e93012..c682fd5b86 100644 --- a/packages/runtime-dom/__tests__/directives/vModel.spec.ts +++ b/packages/runtime-dom/__tests__/directives/vModel.spec.ts @@ -201,7 +201,7 @@ describe('vModel', () => { it('should support modifiers', async () => { const component = defineComponent({ data() { - return { number: null, trim: null, lazy: null } + return { number: null, trim: null, lazy: null, trimNumber: null } }, render() { return [ @@ -229,6 +229,19 @@ describe('vModel', () => { trim: true } ), + withVModel( + h('input', { + class: 'trim-number', + 'onUpdate:modelValue': (val: any) => { + this.trimNumber = val + } + }), + this.trimNumber, + { + trim: true, + number: true + } + ), withVModel( h('input', { class: 'lazy', @@ -248,6 +261,7 @@ describe('vModel', () => { const number = root.querySelector('.number') const trim = root.querySelector('.trim') + const trimNumber = root.querySelector('.trim-number') const lazy = root.querySelector('.lazy') const data = root._vnode.component.data @@ -261,6 +275,16 @@ describe('vModel', () => { await nextTick() expect(data.trim).toEqual('hello, world') + trimNumber.value = ' 1 ' + triggerEvent('input', trimNumber) + await nextTick() + expect(data.trimNumber).toEqual(1) + + trimNumber.value = ' +01.2 ' + triggerEvent('input', trimNumber) + await nextTick() + expect(data.trimNumber).toEqual(1.2) + lazy.value = 'foo' triggerEvent('change', lazy) await nextTick() diff --git a/packages/runtime-dom/src/directives/vModel.ts b/packages/runtime-dom/src/directives/vModel.ts index 3d05e9fa47..1a14decd06 100644 --- a/packages/runtime-dom/src/directives/vModel.ts +++ b/packages/runtime-dom/src/directives/vModel.ts @@ -52,7 +52,8 @@ export const vModelText: ModelDirective< let domValue: string | number = el.value if (trim) { domValue = domValue.trim() - } else if (castToNumber) { + } + if (castToNumber) { domValue = toNumber(domValue) } el._assign(domValue)