Skip to content

Commit

Permalink
fix(v-model): avoid overwriting number input with same value (#7004)
Browse files Browse the repository at this point in the history
close #7003
  • Loading branch information
baiwusanyu-c committed Nov 9, 2023
1 parent 94c049d commit 40f4b77
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 11 deletions.
55 changes: 55 additions & 0 deletions packages/runtime-dom/__tests__/directives/vModel.spec.ts
Expand Up @@ -101,6 +101,61 @@ describe('vModel', () => {
expect(data.value).toEqual(1)
})

// #7003
it('should work with number input and be able to update rendering correctly', async () => {
const setValue1 = function (this: any, value: any) {
this.value1 = value
}
const setValue2 = function (this: any, value: any) {
this.value2 = value
}
const component = defineComponent({
data() {
return { value1: 1.002, value2: 1.002 }
},
render() {
return [
withVModel(
h('input', {
id: 'input_num1',
type: 'number',
'onUpdate:modelValue': setValue1.bind(this)
}),
this.value1
),
withVModel(
h('input', {
id: 'input_num2',
type: 'number',
'onUpdate:modelValue': setValue2.bind(this)
}),
this.value2
)
]
}
})
render(h(component), root)
const data = root._vnode.component.data

const inputNum1 = root.querySelector('#input_num1')!
expect(inputNum1.value).toBe('1.002')

const inputNum2 = root.querySelector('#input_num2')!
expect(inputNum2.value).toBe('1.002')

inputNum1.value = '1.00'
triggerEvent('input', inputNum1)
await nextTick()
expect(data.value1).toBe(1)

inputNum2.value = '1.00'
triggerEvent('input', inputNum2)
await nextTick()
expect(data.value2).toBe(1)

expect(inputNum1.value).toBe('1.00')
})

it('should work with multiple listeners', async () => {
const spy = vi.fn()
const component = defineComponent({
Expand Down
23 changes: 12 additions & 11 deletions packages/runtime-dom/src/directives/vModel.ts
Expand Up @@ -83,24 +83,25 @@ export const vModelText: ModelDirective<
el[assignKey] = getModelAssigner(vnode)
// avoid clearing unresolved text. #2302
if ((el as any).composing) return

const elValue =
number || el.type === 'number' ? looseToNumber(el.value) : el.value
const newValue = value == null ? '' : value

if (elValue === newValue) {
return
}

if (document.activeElement === el && el.type !== 'range') {
if (lazy) {
return
}
if (trim && el.value.trim() === value) {
return
}
if (
(number || el.type === 'number') &&
looseToNumber(el.value) === value
) {
if (trim && el.value.trim() === newValue) {
return
}
}
const newValue = value == null ? '' : value
if (el.value !== newValue) {
el.value = newValue
}

el.value = newValue
}
}

Expand Down

0 comments on commit 40f4b77

Please sign in to comment.