Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug Report] van-time-picker 回显错误 #13084

Open
Alkaidcc opened this issue Aug 26, 2024 · 6 comments
Open

[Bug Report] van-time-picker 回显错误 #13084

Alkaidcc opened this issue Aug 26, 2024 · 6 comments

Comments

@Alkaidcc
Copy link
Contributor

重现链接

https://github.com/Alkaidcc/vant-time-picker-issue

Vant 版本

4.9.4

描述一下你遇到的问题。

需求:使用 van-picker-group,van-date-picker,van-time-picker 实现时间选择器,实现所选结束时间大于开始时间。
使用filter做筛选的时候,数据与UI展示不一致

重现步骤

  1. pnpm install
  2. pnpm dev
CleanShot.2024-08-26.at.14.00.41.mp4

设备/浏览器

macOS/Chrome

@pany-ang
Copy link
Contributor

pany-ang commented Aug 29, 2024

这涉及到两个方面的问题:

  1. 修改 v-model 绑定的数据后,UI 并没有同步进行变化(这应该是一个 BUG
  2. 点击确认按钮时,事件回调参数返回的是内部的私有变量,你所给的 demo 中应该在确认按钮事件触发时使用该回调参数才对,而不是使用 v-model 所绑定的变量。因为该组件并非是完全受控组件,这两者的值有可能不一致。(这种不一致现象,可能是一个 BUG

再说的直白点就是:

  1. v-model 修改为 ['00', '00'] 时,此时 UI 上有 ['00', '00'] 选项,却没有被选中(v-model 变了,但 UI 没变)(这应该是一个 BUG
  2. v-model 修改为 ['00', '00'] 时,此时 UI 上没有 ['00', '00'] 选项,UI 被迫选中最接近的一个值,但是 v-model 没有同步更新为该值,依旧是 ['00', '00'](UI 变了,但 v-model 没变)(可能是一个 BUG

这两个问题在下方最小复现代码中均可复现。

@Alkaidcc
Copy link
Contributor Author

Alkaidcc commented Aug 29, 2024

意思是v-model绑定的变量和组件内部的值实际上不同步是吗?现在的问题是选择开始时间后(时间为00时00分)选择结束时间,由于filter,time-picker会把值变成 ['00','01'] 。但是如果我选中后面一天,我希望time-picker重置为 ['00','00'] 。所以我在结束日期变化的时候判断并修改结束时间的值,奇怪的是如果设置为 ['00','00'] 会和UI不同步,但是设置为 undefined UI就正常了。

function onEndDateChange({ selectedOptions }: any) {
  const endDate = selectedOptions.map((option: any) => option.value).join('-')
  if (dayjs(endDate).isAfter(dayjs(formModel.value.leaveStartTime))) {
    // not working
    formModel.value.endTime = ['00', '00']
  }
}

@pany-ang
Copy link
Contributor

意思是v-model绑定的变量和组件内部的值实际上不同步是吗?现在的问题是选择开始时间后(时间为00时00分)选择结束时间,由于filter,time-picker会把值变成 ['00','01'] 。但是如果我选中后面一天,我希望time-picker重置为 ['00','00'] 。所以我在结束日期变化的时候判断并修改结束时间的值,奇怪的是如果设置为 ['00','00'] 会和UI不同步,但是设置为 undefined UI就正常了。

function onEndDateChange({ selectedOptions }: any) {
  const endDate = selectedOptions.map((option: any) => option.value).join('-')
  if (dayjs(endDate).isAfter(dayjs(formModel.value.leaveStartTime))) {
    // not working
    formModel.value.endTime = ['00', '00']
  }
}

是的,这对应的就是我说的第 1 点,应该是一个 BUG。

@pany-ang
Copy link
Contributor

我试着看了一下相关组件,其中 Picker 组件内部有一个 watch:

watch(
      () => props.modelValue,
      (newValues) => {
        if (
          !isSameValue(newValues, selectedValues.value) &&
          !isSameValue(newValues, lastEmittedModelValue)
        ) {
          selectedValues.value = newValues.slice(0);
          lastEmittedModelValue = newValues.slice(0);
        }
      },
      { deep: true },
    );

如果将其中的 !isSameValue(newValues, lastEmittedModelValue) 移除就能解决第 1 点所说的 BUG,但这是在我不熟悉该组件的情况下找到的修复办法,所以移除这行代码可能会引起其他问题。

牵扯的组件和逻辑有点复杂...要是有空我可能会试着再看看,或者等待其他人来修复这个问题

@pany-ang
Copy link
Contributor

pany-ang commented Aug 29, 2024

你给的 demo 有些冗余,我这里给一个最小复现:

<template>
  <div>
    <van-date-picker v-model="formModel.date" @change="onChange" />
    <van-time-picker
      v-model="formModel.time"
      :filter="filter"
      @confirm="onConfirm"
    />
  </div>
</template>

<script setup>
import { ref } from 'vue';
import VanTimePicker from '../../time-picker';
import VanDatePicker from '../../date-picker';

const formModel = ref({});

function onConfirm(data) {
  console.log('v-model', formModel.value.time);
  console.log('onConfirm', data.selectedValues);
}

function filter(type, options) {
  if (
    type === 'minute' &&
    formModel.value.date?.[1] === '01' &&
    formModel.value.date?.[2] === '01'
  ) {
    return options.filter((option) => Number(option.value) > 0);
  }
  return options;
}

function onChange() {
  formModel.value.time = ['00', '00'];
}
</script>
  • 在复现第 1 个问题时,改变 date-picker 组件的月或日,观察 time-picker 组件即可
  • 在复现第 2 个问题时,需要麻烦一点,要先随意操作 time-picker 组件,然后再改变一下 date-picker 组件的月或日,最后再还原刚才对 date-picker 组件的操作,观察 console.log 输出的值即可。

@pany-ang
Copy link
Contributor

@chenjiahan 可以留意一下这个 issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants