vant icon indicating copy to clipboard operation
vant copied to clipboard

[Bug Report] Calendar组件defaultDate如果在minDate和maxDate之前,会导致选中异常

Open TaurusWood opened this issue 1 year ago • 4 comments

重现链接

https://stackblitz.com/edit/vitejs-vite-cdfwyb?file=src%2Fcomponents%2FACalendar.vue

Vant 版本

4.9.6

描述一下你遇到的问题。

Calendar组件的props属性的顺序问题, 如果defaultDate如果在minDate和maxDate之前,会导致选中异常,不能正常的选择时间段。初步判断是onSelect事件不能正常的区别开始时间和结束时间。

错误复现场景props顺序

 <Calendar
   ...
    :default-date="defaultDate"
    :min-date="new Date('2015-05-01')"
    :max-Date="new Date('2015-09-01')"
    ...
  />

正常场景props顺序

 <Calendar
     ...
    :min-date="new Date('2015-05-01')"
    :max-Date="new Date('2015-09-01')"
:default-date="defaultDate"
    ...
  />

重现步骤

  1. 打开日历弹窗
  2. 选择开始时间,再选择结束时间
  3. 多次切换日期范围,会发现结束日期始终不变,或者开始日期在结束日期之后

设备/浏览器

chrome

TaurusWood avatar Dec 10 '24 09:12 TaurusWood

这个组件是我们基础组件的组件,这个bug还影响了各个业务域。 这可以算是我遇见最神奇的Bug,而且也花费我很多时间来排查这个问题。如果找到原因,请务必告诉我,我真的很好奇,为什么Props的顺序,可以影响组件的逻辑

TaurusWood avatar Dec 10 '24 09:12 TaurusWood

我也试图调试这个bug,但是源码中onSelect事件中繁多的if else条件判断劝退了我,没有那么多时间来排查。😇

TaurusWood avatar Dec 10 '24 09:12 TaurusWood

不要在模版中直接使用类似 min-date="new Date('2015-05-01')" 的写法,把 min-date 作为一个数据定义在 setup 中试一下。

inottn avatar Dec 10 '24 10:12 inottn

不要在模版中直接使用类似 min-date="new Date('2015-05-01')" 的写法,把 min-date 作为一个数据定义在 setup 中试一下。

在demo中确实能解决这个问题,但是在我的实际应用场景并没有解决。 image

我的实际应用场景是拿JSX写的,如何交换红色框两行的顺序就会正常。反之如果defaultDate在min和max之前,还是会出现同样的问题。而且,我还需要把来自外层的props中值为undefined的属性清空掉,才会正常影响。如果restprops中有undefined的值,就会出现相同的错误。这里props的定义来自vant

import { calendarProps } from 'vant';
import { Dayjs } from 'dayjs';
import { ExtractPropTypes, ObjectEmitsOptions } from 'vue';

export const axzoCalendarProps = {
  ...calendarProps,
  showTime: booleanType(false),
  defaultValue: someType<Dayjs | Dayjs[]>(),
  timePanelProps: objectType<TAxzoTimePanelProps>(),
  modelValue: someType<Dayjs | Dayjs[]>(),
  minDate: objectType<Dayjs>(),
  maxDate: objectType<Dayjs>(),
};

export type TAxzoCalendarProps = Partial<ExtractPropTypes<typeof axzoCalendarProps>>;

其中_restprops的打印值如下

{
    allowSameDay: true,
    closeOnClickOverlay: true,
    closeOnPopstate: true,
    color: undefined,
    confirmDisabledText: undefined,
    confirmText: undefined,
    defaultDate: undefined,
    defaultValue: undefined,
    firstDayOfWeek: 0,
    formatter: undefined,
    lazyRender: true,
    maxRange: null,
    poppable: true,
    position: "bottom",
    rangePrompt: undefined,
    readonly: false,
    round: true,
    rowHeight: undefined,
    safeAreaInsetBottom: true,
    safeAreaInsetTop: false,
    show: false,
    showConfirm: true,
    showMark: true,
    showRangePrompt: true,
    showSubtitle: true,
    showTitle: true,
    switchMode: "none",
    teleport: undefined,
    title: undefined,
    type: "range"
}

此外,我比较疑惑,在demo中,为什么在模板里的min-date和max-date变成ref引用就不会出现异常情况。按理说,直接写在模板里,只会把minDate和maxDate变成固定的值,不应该影响功能啊。

TaurusWood avatar Dec 11 '24 02:12 TaurusWood