V-Calendar 日期选择器高级应用指南

V-Calendar 日期选择器高级应用指南

v-calendar An elegant calendar and datepicker plugin for Vue. v-calendar 项目地址: https://gitcode.com/gh_mirrors/vc/v-calendar

前言

V-Calendar 是一个功能强大的 Vue 日历组件库,提供了丰富的日期选择功能。本文将深入探讨 V-Calendar 中几种高级日期选择器的实现方式,包括多日期选择、日期范围选择和按钮式下拉选择器。

多日期选择实现

传统多选模式实现

在 V-Calendar 2.0 版本中,mode: "multiple" 选项已被弃用,但我们仍然可以通过组合使用 attributes 属性和 dayclick 事件来实现多选功能。

实现原理:

  1. 使用 attributes 属性来高亮显示已选日期
  2. 通过 dayclick 事件处理日期选择/取消选择逻辑

代码示例:

<v-calendar :attributes="attributes" @dayclick="onDayClick" />
export default {
  data() {
    return {
      days: [], // 存储已选日期
    };
  },
  computed: {
    // 将日期对象转换为日期字符串数组
    dates() {
      return this.days.map(day => day.date);
    },
    // 生成高亮属性配置
    attributes() {
      return this.dates.map(date => ({
        highlight: true,
        dates: date,
      }));
    },
  },
  methods: {
    // 处理日期点击事件
    onDayClick(day) {
      const idx = this.days.findIndex(d => d.id === day.id);
      if (idx >= 0) {
        // 如果已选中,则取消选择
        this.days.splice(idx, 1);
      } else {
        // 如果未选中,则添加选择
        this.days.push({
          id: day.id,
          date: day.date,
        });
      }
    },
  },
};

按钮式多日期选择器

这是一种更直观的多日期选择方式,每个选中的日期都显示为一个可操作的按钮。

关键特性:

  • 每个日期显示为独立按钮
  • 按钮上提供删除功能
  • 可随时添加新日期

实现要点:

  1. 使用 v-date-picker 组件作为基础
  2. 通过插槽自定义日期显示方式
  3. 实现添加和删除日期的交互逻辑

代码结构分析:

<template>
  <div class="bg-white p-2 w-full border rounded">
    <v-date-picker v-model="selected.date">
      <template #default="{ inputValue, togglePopover, hidePopover }">
        <!-- 日期按钮列表 -->
        <div class="flex flex-wrap">
          <button
            v-for="(date, i) in dates"
            :key="date.date.getTime()"
            class="flex items-center bg-indigo-100 hover:bg-indigo-200 text-sm text-indigo-600 font-semibold h-8 px-2 m-1 rounded-lg border-2 border-transparent focus:border-indigo-600 focus:outline-none"
            @click.stop="dateSelected($event, date, togglePopover)"
            ref="button"
          >
            {{ date.date.toLocaleDateString() }}
            <!-- 删除按钮 -->
            <svg class="w-4 h-4 text-gray-600 hover:text-indigo-600 ml-1 -mr-1" 
                 viewBox="0 0 24 24"
                 stroke="currentColor"
                 stroke-width="2"
                 @click.stop="removeDate(date, hidePopover)">
              <path d="M6 18L18 6M6 6l12 12"></path>
            </svg>
          </button>
        </div>
      </template>
    </v-date-picker>
    <!-- 添加日期按钮 -->
    <button class="text-sm text-indigo-600 font-semibold hover:text-indigo-500 px-2 h-8 focus:outline-none"
            @click.stop="addDate">
      + Add Date
    </button>
  </div>
</template>

日期范围选择器

日期范围选择是许多应用中的常见需求,V-Calendar 提供了便捷的实现方式。

核心功能:

  • 支持选择开始和结束日期
  • 可自定义日期显示格式
  • 提供拖拽选择功能

实现细节:

  1. 使用 is-range 属性启用范围选择模式
  2. 通过 masks 自定义日期显示格式
  3. 利用插槽自定义输入框样式

代码示例:

<template>
  <form class="bg-white rounded-md px-8 pt-6 pb-8" @submit.prevent>
    <div class="mb-4">
      <span class="block text-gray-600 text-sm text-left font-bold mb-2">Select Range</span>
      <v-date-picker
        v-model="range"
        mode="dateTime"
        :masks="masks"
        is-range
      >
        <template v-slot="{ inputValue, inputEvents, isDragging }">
          <!-- 自定义输入框 -->
          <div class="flex flex-col sm:flex-row justify-start items-center">
            <!-- 开始日期输入框 -->
            <div class="relative flex-grow">
              <svg class="text-gray-600 w-4 h-full mx-2 absolute pointer-events-none">
                <!-- 日历图标 -->
              </svg>
              <input
                class="flex-grow pl-8 pr-2 py-1 bg-gray-100 border rounded w-full"
                :class="isDragging ? 'text-gray-600' : 'text-gray-900'"
                :value="inputValue.start"
                v-on="inputEvents.start"
              />
            </div>
            <!-- 分隔箭头 -->
            <span class="flex-shrink-0 m-2">
              <svg class="w-4 h-4 stroke-current text-gray-600" viewBox="0 0 24 24">
                <!-- 箭头图标 -->
              </svg>
            </span>
            <!-- 结束日期输入框 -->
            <div class="relative flex-grow">
              <svg class="text-gray-600 w-4 h-full mx-2 absolute pointer-events-none">
                <!-- 日历图标 -->
              </svg>
              <input
                class="flex-grow pl-8 pr-2 py-1 bg-gray-100 border rounded w-full"
                :class="isDragging ? 'text-gray-600' : 'text-gray-900'"
                :value="inputValue.end"
                v-on="inputEvents.end"
              />
            </div>
          </div>
        </template>
      </v-date-picker>
    </div>
  </form>
</template>

按钮式下拉选择器

对于需要更紧凑布局的场景,按钮式下拉选择器是一个不错的选择。

设计特点:

  • 使用按钮触发日期选择器
  • 输入框为只读,强制使用选择器
  • 简洁直观的交互方式

实现方法:

  1. 使用 v-date-picker 组件
  2. 通过插槽自定义触发按钮和输入框
  3. 设置输入框为只读

代码实现:

<template>
  <v-date-picker class="inline-block h-full" v-model="date">
    <template v-slot="{ inputValue, togglePopover }">
      <div class="flex items-center">
        <!-- 触发按钮 -->
        <button
          class="p-2 bg-blue-100 border border-blue-200 hover:bg-blue-200 text-blue-600 rounded-l focus:bg-blue-500 focus:text-white focus:border-blue-500 focus:outline-none"
          @click="togglePopover()"
        >
          <!-- 日历图标 -->
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" class="w-4 h-4 fill-current">
            <!-- 日历路径 -->
          </svg>
        </button>
        <!-- 只读输入框 -->
        <input
          :value="inputValue"
          class="bg-white text-gray-700 w-full py-1 px-2 appearance-none border rounded-r focus:outline-none focus:border-blue-500"
          readonly
        />
      </div>
    </template>
  </v-date-picker>
</template>

总结

V-Calendar 提供了灵活多样的日期选择方案,开发者可以根据实际需求选择最适合的实现方式。无论是简单的单日期选择,还是复杂的多日期或日期范围选择,V-Calendar 都能提供优雅的解决方案。通过合理使用组件插槽和自定义模板,可以创建出既美观又实用的日期选择界面。

在实际开发中,建议根据应用场景和用户体验需求选择最合适的日期选择器类型,并适当添加自定义样式以保持与整体设计风格的一致性。

v-calendar An elegant calendar and datepicker plugin for Vue. v-calendar 项目地址: https://gitcode.com/gh_mirrors/vc/v-calendar

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姚蔚桑Dominique

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值