mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
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:
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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 />)
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user