This commit is contained in:
hudson 2025-05-05 20:38:32 +00:00 committed by GitHub
commit cc420f19e4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 74 additions and 3 deletions

View File

@ -1377,6 +1377,60 @@ describe('vModel', () => {
expect(data.value).toEqual('使用拼音输入')
})
it('should trasform date to timestamp with numebr modifier', async () => {
const component = defineComponent({
data() {
return { date: null, datetime: null }
},
render() {
return [
withVModel(
h('input', {
class: 'date',
type: 'date',
'onUpdate:modelValue': (val: any) => {
this.date = val
},
}),
this.date,
{
number: true,
},
),
withVModel(
h('input', {
class: 'datetime',
type: 'datetime-local',
'onUpdate:modelValue': (val: any) => {
this.datetime = val
},
}),
this.datetime,
{
number: true,
},
),
]
},
})
render(h(component), root)
const date = root.querySelector('.date')
const datetime = root.querySelector('.datetime')
const data = root._vnode.component.data
date.value = '2024-11-11'
triggerEvent('input', date)
await nextTick()
expect(data.date).toEqual(new Date('2024-11-11').getTime())
datetime.value = '2024-11-11T20:00'
triggerEvent('input', datetime)
await nextTick()
expect(data.datetime).toEqual(new Date('2024-11-11T20:00').getTime())
})
// #10503
it('multiple select (model is number, option value is string)', async () => {
const component = defineComponent({
data() {

View File

@ -8,6 +8,7 @@ import {
} from '@vue/runtime-core'
import { addEventListener } from '../modules/events'
import {
formatDateStamp,
invokeArrayFns,
isArray,
isSet,
@ -53,15 +54,19 @@ export const vModelText: ModelDirective<
> = {
created(el, { modifiers: { lazy, trim, number } }, vnode) {
el[assignKey] = getModelAssigner(vnode)
const castToNumber =
number || (vnode.props && vnode.props.type === 'number')
const vnodeType = vnode.props && vnode.props.type
const castToNumber = number || vnodeType === 'number'
const castToTimeStamp =
number && (vnodeType === 'date' || vnodeType === 'datetime-local')
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) {
if (castToTimeStamp) {
domValue = formatDateStamp(domValue)
} else if (castToNumber) {
domValue = looseToNumber(domValue)
}
el[assignKey](domValue)
@ -111,6 +116,11 @@ export const vModelText: ModelDirective<
if (trim && el.value.trim() === newValue) {
return
}
if (number && (el.type === 'date' || el.type === 'datetime-local')) {
if (formatDateStamp(el.value) === value) {
return
}
}
}
el.value = newValue

View File

@ -217,3 +217,10 @@ export function genCacheKey(source: string, options: any): string {
)
)
}
export function formatDateStamp(dateStr: string): number {
// Handle iOS compatibility issue by replacing - with /
// 2024-11-15T12:37' => 2024/11/15 12:37'
const normalizedDateStr = dateStr.replace(/-/g, '/').replace('T', ' ')
return new Date(normalizedDateStr).getTime()
}