youzan / vant

A lightweight, customizable Vue UI library for mobile web apps.
https://vant.pro/vant/
MIT License
23.28k stars 9.49k forks source link

建议Calendar日历组件增加月份和年份的选择 #12564

Open luckyguanxin opened 9 months ago

luckyguanxin commented 9 months ago

这个功能解决了什么问题?

在某些场景需要选择月份或年份区间,而PickerGroup选择器组的界面不能直观的显示和操作。

你期望的 API 是什么样子的?

### Tasks
nemo-shen commented 9 months ago

@luckyguanxin 你是希望 calendar 顶部的 年/月 可以选择吗?

nemo-shen commented 9 months ago

@luckyguanxin calendardate-picker 都是基础组件,这种复杂的联动看起来不太应该由组件本身实现,这会让 calendar 变的不纯粹而且很重

事实上,目前的 calendardate-picker 提供的API是能支持你实现选择年月的

我给你提供一个代码实现,你可以直接使用

<script setup lang="ts">
import { ref } from 'vue';
import {
  Calendar as VanCalendar,
  DatePicker as VanDatePicker,
  Popup as VanPopup,
  showToast
}, type { CalendarInstance } from 'vant';

const calendarRef = ref<CalendarInstance>();
const showCalendar = ref(false);
const showDatePicker = ref(false);

// 当前展示的年月
const date = new Date();
const yearMonthDate = ref([date.getFullYear().toString(), '01']);

/**
 * 格式化副标题
 * @param date 日期
 */
const formatSubtitle = (date: Date) => {
  if (date) {
    return `${date.getFullYear()}年${date.getMonth() + 1}月`;
  }
};

/**
 * 展示日历
 */
const show = () => {
  showCalendar.value = true;
};

/**
 * 日历【确认】按钮点击
 * @param date 日期
 */
const onConfirm = (date: Date | Date[]) => {
  showToast(date.toLocaleString());
  showCalendar.value = false;
};

/**
 * 日期选择器【确认】按钮点击
 * @param param0 当前选中的年月
 */
const onConfirmDatePicker = ({
  selectedValues,
}: {
  selectedValues: [string, string];
}) => {
  const [year, month] = selectedValues;
  calendarRef.value?.scrollToDate(new Date(Number(year), Number(month) - 1, 1));
  showDatePicker.value = false;
};

/**
 * 点击日历副标题
 * @param date 当前副标题日期
 */
const onClickSubtitle = (date: Date) => {
  yearMonthDate.value = [
    date.getFullYear().toString(),
    (date.getMonth() + 1).toString(),
  ];
  showDatePicker.value = true;
};
</script>
<template>
  <button @click="show">show calendar</button>

  <van-calendar
    ref="calendarRef"
    v-model:show="showCalendar"
    @confirm="onConfirm"
  >
    <template #subtitle="{ date }">
      <span @click="onClickSubtitle(date)">{{ formatSubtitle(date) }}</span>
    </template>
  </van-calendar>

  <van-popup position="bottom" v-model:show="showDatePicker">
    <van-date-picker
      v-model="yearMonthDate"
      :columns-type="['year', 'month']"
      @confirm="onConfirmDatePicker"
    />
  </van-popup>
</template>
nemo-shen commented 9 months ago

11228 @chenjiahan 这个是相同的issue么?我们是需要支持切换年月的能力么?

chenjiahan commented 9 months ago

计划是在 https://github.com/youzan/vant/issues/11228 中提供切换年月的能力,不需要复杂的交互,顶部增加几个切换按钮即可

inottn commented 9 months ago

11228 @chenjiahan 这个是相同的issue么?我们是需要支持切换年月的能力么?

这个 issue 大概是想要可以选择月份或年份区间的能力,类似下图这种交互

image

然后 #11228 这个之前写的差不多的,但是现有的 icon 少一个像这种的

image

DoubleLeft 和 DoubleRight 的图标,就暂时搁置了 😂。

nemo-shen commented 9 months ago

@inottn icon可以用这个么? arrow-left

image

但是,emm,看起来如果是要实现月份区间选择的话,你实现的那个左右切年月是不是就无法做到了?

或者直接按照你截图中的实现?

我的想法是用户触发选择年月的时候会切换成截图里的样子,这样是不是会更方便一点?这样的话,icon的问题是不是也就解决了

image
inottn commented 9 months ago

@nemo-shen 会有同时展示上下月和上下年切换的场景,所以需要两组 icon,单箭头表示上下月切换,双箭头表示上下年切换。 像这样

image image
nemo-shen commented 9 months ago

@inottn 😂 我已经想到了这个样子了,但是就是这个样子的话好像就无法支持区间选择了


我有个想法是这样的,但是仅做参考,因为改动有点。。。大(或者可以单独提供月份calendar和年份calendar)

CleanShot 2024-01-11 at 22 23 52@2x

nemo-shen commented 9 months ago

@inottn icon的问题我明天去问问吧,但是大概率会被驳回🤣

@chenjiahan fork一份icon,我们自己画口不口以?毕竟sketch也是开源的 🤡 (仅限vant4)

chenjiahan commented 9 months ago

我有个想法是这样的,但是仅做参考,因为改动有点。。。大(或者可以单独提供月份calendar和年份calendar)

这个交互可能有点少见,用户不太会用。。月份 calendar 和年 份calendar 倒没必要,用 picker 就行

nemo-shen commented 9 months ago

我有个想法是这样的,但是仅做参考,因为改动有点。。。大(或者可以单独提供月份calendar和年份calendar)

这个交互可能有点少见,用户不太会用。。月份 calendar 和年 份calendar 倒没必要,用 picker 就行

get~

luckyguanxin commented 9 months ago

@nemo-shen 我描述的就是想要月份 calendar 和年 份calendar的区间选择,虽然我用PickerGroup选择器组实现了,但是在交互上不是很好,需要进行切换 CleanShot 2024-01-11 at 22 23 52@2x

我描述的就是想要月份 calendar 和年 份calendar的区间选择,虽然我用PickerGroup选择器组实现了,但是在交互上不是很好,需要进行切换

yueyunkeji commented 9 months ago

所以现在4.8.2有这个效果了吗

zybieku commented 4 months ago

@inottn icon可以用这个么? arrow-left image

但是,emm,看起来如果是要实现月份区间选择的话,你实现的那个左右切年月是不是就无法做到了?

或者直接按照你截图中的实现?

我的想法是用户触发选择年月的时候会切换成截图里的样子,这样是不是会更方便一点?这样的话,icon的问题是不是也就解决了 image

+1