diff --git a/packages/varlet-ui/src/date-picker/DatePicker.vue b/packages/varlet-ui/src/date-picker/DatePicker.vue index 9a1abc54947..c80a66123e0 100644 --- a/packages/varlet-ui/src/date-picker/DatePicker.vue +++ b/packages/varlet-ui/src/date-picker/DatePicker.vue @@ -22,7 +22,7 @@ -
+
{{ getMonthTitle }} @@ -33,7 +33,7 @@ {{ getMonthTitle }}
-
+
{{ getDateTitle }} @@ -107,16 +107,16 @@ export default defineComponent({ const isYearPanel: Ref = ref(false) const isMonthPanel: Ref = ref(false) const rangeDone: Ref = ref(true) - const chooseMonth: Ref = ref(monthDes) - const chooseYear: Ref = ref(currentYear) - const chooseDay: Ref = ref(currentDay) + const chooseMonth: Ref = ref() + const chooseYear: Ref = ref() + const chooseDay: Ref = ref() const previewMonth: Ref = ref(monthDes) const previewYear: Ref = ref(currentYear) const reverse: Ref = ref(false) - const chooseMonths: Ref> = ref([`${currentYear}-${currentMonth}`]) - const chooseDays: Ref> = ref([currentDate]) - const chooseRangeMonth: Ref> = ref([`${currentYear}-${currentMonth}`]) - const chooseRangeDay: Ref> = ref([currentDate]) + const chooseMonths: Ref> = ref([]) + const chooseDays: Ref> = ref([]) + const chooseRangeMonth: Ref> = ref([]) + const chooseRangeDay: Ref> = ref([]) const componentProps: UnwrapRef = reactive({ allowedDates: props.allowedDates, @@ -148,9 +148,14 @@ export default defineComponent({ const getMonthTitle: ComputedRef = computed(() => { const { multiple, range } = props - if (range) return `${chooseRangeMonth.value[0]} ~ ${chooseRangeMonth.value[1]}` + if (range) { + return chooseRangeMonth.value.length ? `${chooseRangeMonth.value[0]} ~ ${chooseRangeMonth.value[1]}` : '' + } - const monthName = pack.value.datePickerMonthDict?.[chooseMonth.value.index].name ?? '' + let monthName = '' + if (chooseMonth.value) { + monthName = pack.value.datePickerMonthDict?.[chooseMonth.value.index].name ?? '' + } return multiple ? `${chooseMonths.value.length}${pack.value.datePickerSelected}` : monthName }) @@ -160,11 +165,12 @@ export default defineComponent({ if (range) { const formatRangeDays = chooseRangeDay.value.map((date) => dayjs(date).format('YYYY-MM-DD')) - return `${formatRangeDays[0]} ~ ${formatRangeDays[1]}` + return formatRangeDays.length ? `${formatRangeDays[0]} ~ ${formatRangeDays[1]}` : '' } if (multiple) return `${chooseDays.value.length}${pack.value.datePickerSelected}` + if (!chooseYear.value || !chooseMonth.value || !chooseDay.value) return '' const weekIndex = dayjs(`${chooseYear.value}-${chooseMonth.value.index}-${chooseDay.value}`).day() const week: WeekDict = WEEK_HEADER.find((value) => value.index === `${weekIndex}`) as WeekDict const weekName = pack.value.datePickerWeekDict?.[week.index].name ?? '' @@ -177,13 +183,13 @@ export default defineComponent({ }) const slotProps: ComputedRef> = computed(() => { - const weekIndex = dayjs(`${chooseYear.value}-${chooseMonth.value.index}-${chooseDay.value}`).day() + const weekIndex = dayjs(`${chooseYear.value}-${chooseMonth.value?.index}-${chooseDay.value}`).day() return { week: `${weekIndex}`, - year: chooseYear.value, - month: chooseMonth.value.index, - date: chooseDay.value, + year: chooseYear.value ?? '', + month: chooseMonth.value?.index ?? '', + date: chooseDay.value ?? '', } }) @@ -192,7 +198,7 @@ export default defineComponent({ ) const isSameYear: ComputedRef = computed(() => chooseYear.value === previewYear.value) - const isSameMonth: ComputedRef = computed(() => chooseMonth.value.index === previewMonth.value.index) + const isSameMonth: ComputedRef = computed(() => chooseMonth.value?.index === previewMonth.value.index) const clickEl = (type: string) => { if (type === 'year') isYearPanel.value = true @@ -232,6 +238,7 @@ export default defineComponent({ } const getReverse = (dateType: string, date: MonthDict | number) => { + if (!chooseYear.value || !chooseMonth.value) return false if (!isSameYear.value) return chooseYear.value > previewYear.value if (dateType === 'month') return (date as MonthDict).index < chooseMonth.value.index @@ -321,7 +328,7 @@ export default defineComponent({ const invalidFormatDate = (date: string | Array | undefined): boolean => { if (isArray(date)) return false - if (date === undefined || date === 'Invalid Date') { + if (date === 'Invalid Date') { console.error('[Varlet] DatePicker: "modelValue" is an Invalid Date') return true } @@ -374,7 +381,7 @@ export default defineComponent({ watch( () => props.modelValue, (value) => { - if (!checkValue() || invalidFormatDate(value)) return + if (!checkValue() || invalidFormatDate(value) || !value) return if (props.range) { if (!isArray(value)) return diff --git a/packages/varlet-ui/src/date-picker/__tests__/index.spec.js b/packages/varlet-ui/src/date-picker/__tests__/index.spec.js index 5661692612e..4b04a488514 100644 --- a/packages/varlet-ui/src/date-picker/__tests__/index.spec.js +++ b/packages/varlet-ui/src/date-picker/__tests__/index.spec.js @@ -255,7 +255,7 @@ test('test value legal', async () => { await delay(0) await wrapper.setData({ multiple: false, date: [] }) await delay(0) - await wrapper.setData({ multiple: false, date: undefined }) + await wrapper.setData({ multiple: false, date: 'Invalid Date' }) expect(fn).toHaveBeenCalledTimes(3) mockRestore() diff --git a/packages/varlet-ui/src/date-picker/docs/en-US.md b/packages/varlet-ui/src/date-picker/docs/en-US.md index 319e3f63d2b..a37483ed54b 100644 --- a/packages/varlet-ui/src/date-picker/docs/en-US.md +++ b/packages/varlet-ui/src/date-picker/docs/en-US.md @@ -139,7 +139,7 @@ export default { | Prop | Description | Type | Default | | ----- | -------------- | -------- | ---------- | -| `v-model` | Selected date(ISO 8601 format, `YYYY-MM-DD` or `YYYY-MM`)| _string[] \| string_ | `-` | +| `v-model` | Selected date(ISO 8601 format, `YYYY-MM-DD` or `YYYY-MM`)| _string[] \| string_ | `undefined` | | `type` | Picker type, optional values`date, month` | _string_ | `date` | | `allowed-dates` | Restricts which dates can be selected | _function_ | `-` | | `color` | Picker color | _string_ | `#2979ff` | diff --git a/packages/varlet-ui/src/date-picker/docs/zh-CN.md b/packages/varlet-ui/src/date-picker/docs/zh-CN.md index 0da78d68fc5..825ef145159 100644 --- a/packages/varlet-ui/src/date-picker/docs/zh-CN.md +++ b/packages/varlet-ui/src/date-picker/docs/zh-CN.md @@ -138,21 +138,21 @@ export default { ### 属性 -| 参数 | 说明 | 类型 | 默认值 | -| ----- | -------------- | -------- | ---------- | -| `v-model` | 被选择的日期(ISO 8601 格式,`YYYY-MM-DD` 或 `YYYY-MM`)| _string[] \| string_ | `-` | -| `type` | 选择器类型,可选值为 `date, month` | _string_ | `date` | -| `allowed-dates` | 限制可以选择的日期 | _function_ | `-` | -| `color` | 选择器的颜色 | _string_ | `#2979ff` | -| `header-color` | 标题背景色。如果未指定,将使用由 color 属性或默认颜色。 | _string_ | `#2979ff` | -| `shadow` | 是否添加阴影 | _boolean_ | `false` | +| 参数 | 说明 | 类型 | 默认值 | +|---------------------| -------------- | -------- | ---------- | +| `v-model` | 被选择的日期(ISO 8601 格式,`YYYY-MM-DD` 或 `YYYY-MM`)| _string[] \| string_ | `undefined` | +| `type` | 选择器类型,可选值为 `date, month` | _string_ | `date` | +| `allowed-dates` | 限制可以选择的日期 | _function_ | `-` | +| `color` | 选择器的颜色 | _string_ | `#2979ff` | +| `header-color` | 标题背景色。如果未指定,将使用由 color 属性或默认颜色。 | _string_ | `#2979ff` | +| `shadow` | 是否添加阴影 | _boolean_ | `false` | | `first-day-of-week` | 设置一周的第一天,从周日的 0 开始。 | _string \| number_ | `0` | -| `min` | 允许的最小日期/月份(ISO 8601格式) | _string_ | `-` | -| `max` | 允许的最大日期/月份(ISO 8601格式) | _string_ | `-` | -| `show-current` | 是否显示当前日期 | _boolean_ | `true` | -| `readonly` | 是否只读 | _boolean_ | `false` | -| `multiple` | 是否支持选择多个日期 | _boolean_ | `false` | -| `range` | 是否支持选择一个范围 | _boolean_ | `false` | +| `min` | 允许的最小日期/月份(ISO 8601格式) | _string_ | `-` | +| `max` | 允许的最大日期/月份(ISO 8601格式) | _string_ | `-` | +| `show-current` | 是否显示当前日期 | _boolean_ | `true` | +| `readonly` | 是否只读 | _boolean_ | `false` | +| `multiple` | 是否支持选择多个日期 | _boolean_ | `false` | +| `range` | 是否支持选择一个范围 | _boolean_ | `false` | ### 事件 diff --git a/packages/varlet-ui/src/date-picker/props.ts b/packages/varlet-ui/src/date-picker/props.ts index bcd58115d33..27fdb6bd1da 100644 --- a/packages/varlet-ui/src/date-picker/props.ts +++ b/packages/varlet-ui/src/date-picker/props.ts @@ -38,9 +38,9 @@ export type PanelBtnDisabled = { } export type Choose = { - chooseMonth: MonthDict - chooseYear: string - chooseDay: string + chooseMonth: MonthDict | undefined + chooseYear: string | undefined + chooseDay: string | undefined chooseMonths: Array chooseDays: Array chooseRangeMonth: Array diff --git a/packages/varlet-ui/src/date-picker/src/day-picker-panel.vue b/packages/varlet-ui/src/date-picker/src/day-picker-panel.vue index cc99a142a54..3806078713b 100644 --- a/packages/varlet-ui/src/date-picker/src/day-picker-panel.vue +++ b/packages/varlet-ui/src/date-picker/src/day-picker-panel.vue @@ -102,7 +102,7 @@ export default defineComponent({ const isSame: ComputedRef = computed( () => props.choose.chooseYear === props.preview.previewYear && - props.choose.chooseMonth.index === props.preview.previewMonth.index + props.choose.chooseMonth?.index === props.preview.previewMonth.index ) const sortWeekList: ComputedRef> = computed(() => { @@ -165,9 +165,9 @@ export default defineComponent({ componentProps: { range }, }: { choose: Choose; componentProps: ComponentProps } = props - if (!chooseRangeDay.length) return false - if (range) { + if (!chooseRangeDay.length) return false + const isBeforeMax = dayjs(val).isSameOrBefore(dayjs(chooseRangeDay[1]), 'day') const isAfterMin = dayjs(val).isSameOrAfter(dayjs(chooseRangeDay[0]), 'day') return isBeforeMax && isAfterMin diff --git a/packages/varlet-ui/src/date-picker/src/month-picker-panel.vue b/packages/varlet-ui/src/date-picker/src/month-picker-panel.vue index 473773ae8c5..3f9ec9b80d2 100644 --- a/packages/varlet-ui/src/date-picker/src/month-picker-panel.vue +++ b/packages/varlet-ui/src/date-picker/src/month-picker-panel.vue @@ -113,9 +113,9 @@ export default defineComponent({ componentProps: { type, range }, }: { choose: Choose; componentProps: ComponentProps } = props - if (!chooseRangeMonth.length) return false - if (range) { + if (!chooseRangeMonth.length) return false + const isBeforeMax = dayjs(val).isSameOrBefore(dayjs(chooseRangeMonth[1]), 'month') const isAfterMin = dayjs(val).isSameOrAfter(dayjs(chooseRangeMonth[0]), 'month') @@ -137,7 +137,7 @@ export default defineComponent({ const monthExist = (): boolean => { if (range || multiple) return shouldChoose(val) - return chooseMonth.index === key && isSameYear.value + return chooseMonth?.index === key && isSameYear.value } const computeDisabled = (): boolean => { @@ -150,7 +150,7 @@ export default defineComponent({ const computeText = (): boolean => { if (disabled) return true if (range || multiple) return !shouldChoose(val) - return !isSameYear.value || chooseMonth.index !== key + return !isSameYear.value || chooseMonth?.index !== key } const computeOutline = (): boolean => { @@ -164,7 +164,7 @@ export default defineComponent({ if (range || multiple) return !shouldChoose(val) // 同一年但是未被选择的情况 - if (isSameYear.value) return chooseMonth.index !== currentMonth + if (isSameYear.value) return chooseMonth?.index !== currentMonth return true }