fix(components): [date-picker] resolve v-model type inconsistency (#18888)

* fix(components): [date-picker] resolve  v-model type inconsistency

* test: add unit test form CommonPicker
This commit is contained in:
DDDDD12138
2024-11-23 17:44:43 +08:00
committed by GitHub
parent ad2f8507a0
commit 776ae477fe
4 changed files with 51 additions and 18 deletions

View File

@@ -13,6 +13,8 @@ import {
CommonPicker,
DEFAULT_FORMATS_DATE,
DEFAULT_FORMATS_DATEPICKER,
type DateModelType,
type SingleOrRange,
} from '@element-plus/components/time-picker'
import { ROOT_PICKER_INJECTION_KEY } from './constants'
@@ -61,7 +63,7 @@ export default defineComponent({
expose(refProps)
const onModelValueUpdated = (val: any) => {
const onModelValueUpdated = (val: SingleOrRange<DateModelType> | null) => {
emit('update:modelValue', val)
}

View File

@@ -385,6 +385,41 @@ describe('TimePicker', () => {
expect(value.value).toEqual('2000-01-01 09:00:00')
})
it('when a time is input, the type of modelValue should be Date by default', async () => {
const value = ref('2024-11-18 12:00:00')
const wrapper = mount(() => <TimePicker v-model={value.value} />)
const input = wrapper.find('input')
input.trigger('focus')
await input.setValue('10:00:00')
input.trigger('blur')
expect(value.value).toBeInstanceOf(Date)
})
it('when a time is input, the type of modelValue should be Date by default (is-range)', async () => {
const value = ref([
new Date('2024-11-18 10:00:00'),
new Date('2024-11-18 12:00:00'),
])
const wrapper = mount(() => <TimePicker v-model={value.value} is-range />)
const [startTimeInput, endTimeInput] = wrapper.findAll('input')
// Input start time
startTimeInput.trigger('focus')
await startTimeInput.setValue('10:00:10')
startTimeInput.trigger('blur')
expect(value.value[0]).toBeInstanceOf(Date)
// Input end time
endTimeInput.trigger('focus')
await endTimeInput.setValue('12:00:10')
endTimeInput.trigger('blur')
expect(value.value[1]).toBeInstanceOf(Date)
})
it('picker-panel should not pop up when readonly', async () => {
const wrapper = mount(() => <TimePicker readonly />)

View File

@@ -180,7 +180,7 @@ import ElTooltip from '@element-plus/components/tooltip'
import { NOOP, debugWarn, isArray } from '@element-plus/utils'
import { EVENT_CODE } from '@element-plus/constants'
import { Calendar, Clock } from '@element-plus/icons-vue'
import { formatter, parseDate, valueEquals } from '../utils'
import { dayOrDaysToDate, formatter, parseDate, valueEquals } from '../utils'
import { timePickerDefaultProps } from './props'
import PickerRangeTrigger from './picker-range-trigger.vue'
import type { InputInstance } from '@element-plus/components/input'
@@ -190,7 +190,6 @@ import type { ComponentPublicInstance, Ref } from 'vue'
import type { Options } from '@popperjs/core'
import type {
DateModelType,
DateOrDates,
DayOrDays,
PickerOptions,
SingleOrRange,
@@ -199,8 +198,6 @@ import type {
} from './props'
import type { TooltipInstance } from '@element-plus/components/tooltip'
// Date object and string
defineOptions({
name: 'Picker',
})
@@ -299,7 +296,7 @@ const emitChange = (
formItem?.validate('change').catch((err) => debugWarn(err))
}
}
const emitInput = (input: SingleOrRange<DateModelType | Dayjs> | null) => {
const emitInput = (input: SingleOrRange<DateModelType> | null) => {
if (!valueEquals(props.modelValue, input)) {
let formatted
if (isArray(input)) {
@@ -402,11 +399,7 @@ const parsedValue = computed(() => {
// The result is corrected only when model-value exists
if (!valueIsEmpty.value) {
emitInput(
(isArray(dayOrDays)
? dayOrDays.map((_) => _.toDate())
: dayOrDays.toDate()) as SingleOrRange<Date>
)
emitInput(dayOrDaysToDate(dayOrDays))
}
}
}
@@ -540,11 +533,7 @@ const handleChange = () => {
const value = parseUserInputToDayjs(displayValue.value)
if (value) {
if (isValidValue(value)) {
emitInput(
(isArray(value)
? value.map((_) => _.toDate())
: value.toDate()) as DateOrDates
)
emitInput(dayOrDaysToDate(value))
userInput.value = null
}
}
@@ -664,7 +653,7 @@ const handleStartChange = () => {
]
const newValue = [value, parsedVal && (parsedVal[1] || null)] as DayOrDays
if (isValidValue(newValue)) {
emitInput(newValue)
emitInput(dayOrDaysToDate(newValue))
userInput.value = null
}
}
@@ -681,7 +670,7 @@ const handleEndChange = () => {
]
const newValue = [parsedVal && parsedVal[0], value] as DayOrDays
if (isValidValue(newValue)) {
emitInput(newValue)
emitInput(dayOrDaysToDate(newValue))
userInput.value = null
}
}

View File

@@ -2,6 +2,7 @@ import dayjs from 'dayjs'
import { isArray, isDate, isEmpty } from '@element-plus/utils'
import type { Dayjs } from 'dayjs'
import type { DateOrDates, DayOrDays } from './common/props'
export type TimeList = [number | undefined, number, undefined | number]
export const buildTimeList = (value: number, bound: number): TimeList => {
@@ -88,3 +89,9 @@ export const makeList = (total: number, method?: () => number[]) => {
}
return arr
}
export const dayOrDaysToDate = (dayOrDays: DayOrDays): DateOrDates => {
return isArray(dayOrDays)
? (dayOrDays.map((d) => d.toDate()) as [Date, Date])
: dayOrDays.toDate()
}