Ver código fonte

fix(v-model): handle number modifier on change (#13959)

close #13958
rzzf 5 meses atrás
pai
commit
8fbe48fe39

+ 3 - 0
packages/runtime-dom/__tests__/directives/vModel.spec.ts

@@ -345,6 +345,9 @@ describe('vModel', () => {
     triggerEvent('input', number)
     await nextTick()
     expect(data.number).toEqual(1.2)
+    triggerEvent('change', number)
+    await nextTick()
+    expect(number.value).toEqual('1.2')
 
     trim.value = '    hello, world    '
     triggerEvent('input', trim)

+ 9 - 10
packages/runtime-dom/src/directives/vModel.ts

@@ -45,6 +45,12 @@ type ModelDirective<T, Modifiers extends string = string> = ObjectDirective<
   Modifiers
 >
 
+function castValue(value: string, trim?: boolean, number?: boolean | null) {
+  if (trim) value = value.trim()
+  if (number) value = looseToNumber(value)
+  return value
+}
+
 // We are exporting the v-model runtime directly as vnode hooks so that it can
 // be tree-shaken in case v-model is never used.
 export const vModelText: ModelDirective<
@@ -57,18 +63,11 @@ export const vModelText: ModelDirective<
       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
-      if (trim) {
-        domValue = domValue.trim()
-      }
-      if (castToNumber) {
-        domValue = looseToNumber(domValue)
-      }
-      el[assignKey](domValue)
+      el[assignKey](castValue(el.value, trim, castToNumber))
     })
-    if (trim) {
+    if (trim || castToNumber) {
       addEventListener(el, 'change', () => {
-        el.value = el.value.trim()
+        el.value = castValue(el.value, trim, castToNumber)
       })
     }
     if (!lazy) {