日期范围选择组件技术文档

95 阅读3分钟

日期范围选择组件技术文档

功能概述

该组件实现了一个日期范围选择功能,可用于选择连续的日期范围,支持上一页、下一页切换,同时包含一个日期选择器,可快速跳转到特定日期。该功能适用于需要展示和管理日期数据的场景,例如排班管理、日程规划等。

主要功能

  1. 日期范围展示

    • 默认展示当前日期所在的范围。
    • 支持每页显示固定数量的日期(默认 7 天)。
  2. 导航功能

    • 支持通过“上一页”和“下一页”按钮切换日期范围。
    • 可快速跳转回当天日期。
  3. 日期选择器

    • 提供一个日期选择器,用户可直接选中具体日期。
    • 选中日期后会定位到包含该日期的页面。
  4. 日期高亮

    • 当前日期和选中日期有不同的高亮样式,便于用户识别。

使用方法

引入组件

在 Vue 3 项目中,确保已安装 Element Plus 组件库,随后将该组件代码复制到项目中。

代码结构

YAML 路由配置
<route lang="yaml">
meta:
  title: 日期范围选择
</route>
脚本部分
核心状态
import { computed, ref } from 'vue';
import { ArrowLeft, ArrowRight } from '@element-plus/icons-vue';

const currentDate = ref(new Date());
const selectedDate = ref<Date | null>(null);
const pageSize = 7; // 每页显示7天
const startDate = ref(new Date());

const selectedDatePicker = ref(new Date().toISOString().split('T')[0]);
主要方法
// 计算日期范围
const dateRange = computed(() => {
  const dates = [];
  const start = new Date(startDate.value);
  for (let i = 0; i < pageSize; i++) {
    const date = new Date(start);
    date.setDate(start.getDate() + i);
    dates.push(date);
  }
  return dates;
});

function previousPage() {
  const newStart = new Date(startDate.value);
  newStart.setDate(newStart.getDate() - pageSize);
  startDate.value = newStart;
}

function nextPage() {
  const newStart = new Date(startDate.value);
  newStart.setDate(newStart.getDate() + pageSize);
  startDate.value = newStart;
}

function goToToday() {
  const today = new Date();
  startDate.value = today;
  selectedDate.value = today;
  selectedDatePicker.value = today.toISOString().split('T')[0];
}

function selectDate(date: Date) {
  selectedDate.value = date;
  selectedDatePicker.value = date.toISOString().split('T')[0];
}

function isSelected(date: Date) {
  return selectedDate.value?.toDateString() === date.toDateString();
}

function isToday(date: Date) {
  const today = new Date();
  return date.toDateString() === today.toDateString();
}

function handleDateChange(val: string) {
  if (!val) return;
  const date = new Date(val);
  selectedDate.value = date;

  const currentStartDate = new Date(startDate.value);
  const currentEndDate = new Date(currentStartDate);
  currentEndDate.setDate(currentEndDate.getDate() + pageSize - 1);

  if (date < currentStartDate || date > currentEndDate) {
    const newStart = new Date(date);
    newStart.setDate(date.getDate() - date.getDay());
    startDate.value = newStart;
  }
}
模板部分
<template>
  <div>
    <PageMain>
      <div class="date-range-picker">
        <div class="date-selection-area">
          <el-button :icon="ArrowLeft" class="nav-button" @click="previousPage">
            上一页
          </el-button>

          <div class="date-grid">
            <div
              v-for="date in dateRange"
              :key="date.toISOString()"
              class="date-cell"
              :class="{
                selected: isSelected(date),
                today: isToday(date),
              }"
              @click="selectDate(date)"
            >
              <div class="weekday">
                {{ formatWeekday(date) }}
              </div>
              <div class="date">
                {{ formatDate(date) }}
              </div>
            </div>
          </div>

          <el-button :icon="ArrowRight" class="nav-button" @click="nextPage">
            下一页
          </el-button>

          <div class="year-month-selector">
            <el-date-picker
              v-model="selectedDatePicker"
              type="date"
              format="YYYY年MM月DD日"
              value-format="YYYY-MM-DD"
              placeholder="选择日期"
              @change="handleDateChange"
            />
            <el-button type="primary" @click="goToToday">
              回到今天
            </el-button>
          </div>
        </div>
      </div>
    </PageMain>
  </div>
</template>
样式部分
<style scoped>
.date-range-picker {
  max-width: 1200px;
  padding: 20px;
  margin: 0 auto;
}

.date-selection-area {
  display: flex;
  gap: 20px;
  align-items: center;
  justify-content: center;
}

.year-month-selector {
  display: flex;
  gap: 10px;
  align-items: center;
}

.nav-button {
  height: fit-content;
}

.date-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 10px;
  min-width: 700px;
  max-width: 900px;
}

.date-cell {
  padding: 10px;
  text-align: center;
  cursor: pointer;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  transition: all 0.3s;
}

.date-cell:hover {
  background-color: #f5f7fa;
}

.date-cell.selected {
  color: white;
  background-color: #409eff;
}

.date-cell.today {
  border-color: #409eff;
}

.weekday {
  font-size: 12px;
  color: #909399;
}

.date {
  margin-top: 4px;
  font-size: 16px;
}

.selected .weekday {
  color: #fff;
}
</style>

使用注意事项

  1. 依赖项

    • 需要安装 Element Plus
  2. 适配调整

    • 日期范围展示区域的样式根据具体页面的需求进行调整。
  3. 国际化支持

    • 当前组件的日期展示和格式化为中文,若需支持其他语言,需要调整 formatWeekdayel-date-picker 的国际化设置。

示例效果

组件运行后,可以实现日期范围的快速选择与切换,当前日期和选中日期高亮,用户体验友好。

b7dbc5b5d22b2094de89a46c9a09c0b.png