Skip to content

DateRange

DateRange 是一個功能豐富的日期範圍選擇器組件,支援雙日曆顯示、快捷選項、範圍限制和完整的國際化功能。

主要功能

日期範圍選擇與輸入

基本日期範圍選擇

點擊選擇開始和結束日期,支援雙日曆顯示

包含時間範圍

選擇日期後可設定開始和結束時間

必填驗證

即時驗證並顯示錯誤訊息

vue
<template>
  <!-- 基本範圍選擇 -->
  <DateRange v-model="basicRange" />

  <!-- 包含時間範圍 -->
  <DateRange v-model="timeRange" :showTime="true" />

  <!-- 必填驗證 -->
  <DateRange v-model="requiredRange" required />
</template>

輸入框直接輸入

輸入框輸入

可在日曆中直接使用輸入框輸入日期範圍

僅日曆選擇

隱藏輸入框,僅使用日曆進行選擇

vue
<template>
  <!-- 啟用輸入框 -->
  <DateRange v-model="inputRange" :inputEnabled="true" />

  <!-- 僅日曆選擇 -->
  <DateRange v-model="calendarOnlyRange" :inputEnabled="false" />
</template>

WARNING

輸入功能僅限於 monthDisplayMode 為 dual 的情況下

日曆顯示模式

雙月顯示模式

同時顯示兩個連續月份的日曆,方便選擇跨月範圍

單月顯示模式

僅顯示單個月份日曆,節省顯示空間

自動模式(預設)

根據螢幕寬度自動切換:桌面版顯示雙月,行動版顯示單月

vue
<template>
  <!-- 強制雙月顯示 -->
  <DateRange v-model="dualModeRange" monthDisplayMode="dual" />

  <!-- 強制單月顯示 -->
  <DateRange v-model="singleModeRange" monthDisplayMode="single" />

  <!-- 自動適應(預設行為) -->
  <DateRange v-model="autoModeRange" />
</template>

快捷選項

內建快捷選項

提供今天、最近7天、最近30天、本月等快捷選項

vue
<template>
  <!-- 顯示快捷選項 -->
  <DateRange v-model="shortcutRange" :showShortcuts="true" />
</template>

範圍限制

最大範圍限制

最多只能選擇 7 天的範圍

最小範圍限制

至少要選擇 3 天的範圍

日期範圍限制

限制可選日期範圍: 2025-01-01 ~ 2025-12-31

vue
<template>
  <!-- 最大範圍限制 -->
  <DateRange v-model="maxRangeLimit" :maxRange="7" />

  <!-- 最小範圍限制 -->
  <DateRange v-model="minRangeLimit" :minRange="3" />

  <!-- 日期範圍限制 -->
  <DateRange
    v-model="dateConstrainedRange"
    :minDate="minDate"
    :maxDate="maxDate"
  />
</template>

Props 參數

基本屬性

屬性類型預設值說明
modelValue{ start: DateTimeInput; end: DateTimeInput } | nullnull綁定的日期範圍值
disabledbooleanfalse是否禁用
requiredbooleanfalse是否必填
showClearButtonbooleantrue是否顯示清除按鈕
separatorstring' ~ '開始和結束日期間分隔符

日曆系統

屬性類型預設值說明
calendarstring'gregory'日曆系統 ('gregory', 'roc')
localestring'zh-TW'語言環境
weekStartsOn0-60一週起始日 (0=週日)

日期格式

屬性類型預設值說明
dateFormatstring'YYYY-MM-DD'日期格式
dateSeparatorstring'-'日期分隔符
outputTypeOutputType'iso'輸出格式類型
useStrictISObooleanfalse嚴格 ISO 格式

時間選項

屬性類型預設值說明
showTimebooleanfalse是否顯示時間選擇
timeFormatstringundefined時間格式(依照 enableSeconds 及 use24Hour 預設)
enableSecondsbooleantrue是否啟用秒
use24Hourbooleantrue是否使用 24 小時制

範圍特定選項

屬性類型預設值說明
monthDisplayMode'single' | 'dual'undefined日曆顯示模式,未設定時依照視窗大小自動切換
showShortcutsbooleanfalse是否顯示快捷選項
incompletebooleantrue是否提示不完整的範圍選擇
maxRangenumberundefined允許選擇的最大天數
minRangenumberundefined允許選擇的最小天數
minDatestringundefined最小可選日期
maxDatestringundefined最大可選日期

主題外觀

屬性類型預設值說明
mode'light' | 'dark' | 'auto''auto'主題模式
themeTailwindColor | string'violet'主題顏色

國際化與錯誤處理

屬性類型預設值說明
customLocaleMessagesLocaleMessagesundefined自定義語言包
customErrorMessagesRecord<string, string>{}自定義錯誤訊息
useI18nbooleantrue是否使用內建國際化
showErrorMessagebooleantrue是否顯示錯誤訊息

輸入控制

屬性類型預設值說明
inputEnabledbooleanfalse是否允許輸入框輸入
placeholderOverridesPlaceholderOverrides{}自定義佔位符
autoFocusTimeAfterDatebooleantrue是否自動聚焦到時間輸入框

PlaceholderOverrides 介面:

typescript
interface PlaceholderOverrides {
  start?: string; // 開始日期的提示文字
  end?: string; // 結束日期的提示文字
  year?: string; // 年份輸入框佔位符
  month?: string; // 月份輸入框佔位符
  day?: string; // 日期輸入框佔位符
  hour?: string; // 小時輸入框佔位符
  minute?: string; // 分鐘輸入框佔位符
  second?: string; // 秒數輸入框佔位符
}

Events 事件

事件名稱參數說明
update:modelValue(range: { start: DateTimeInput; end: DateTimeInput } | null)範圍值變化時觸發
change(range: { start: DateTimeInput; end: DateTimeInput } | null)使用者操作改變值時觸發
validation(isValid: boolean, errors: Record<string, string>, errorParams?: Record<string, Record<string, any>>)驗證狀態變化時觸發

高級功能

多種日曆系統

西元曆 (Gregorian)

民國曆 (ROC)

vue
<template>
  <!-- 西元曆 -->
  <DateRange v-model="gregorianRange" calendar="gregory" />

  <!-- 民國曆 -->
  <DateRange v-model="rocRange" calendar="roc" outputType="custom" />
</template>

TIP

更多日曆系統請參考 calendar

主題模式

淺色模式

深色模式

vue
<template>
  <!-- 不同主題模式 -->
  <DateRange v-model="lightRange" mode="light" theme="blue" />
  <DateRange v-model="darkRange" mode="dark" theme="emerald" />
</template>

TIP

更多主題相關請參考 theme

時間配置

24小時制時間範圍

12小時制時間範圍

無秒數時間範圍

vue
<template>
  <!-- 24小時制 -->
  <DateRange v-model="time24Range" :showTime="true" :use24Hour="true" />

  <!-- 12小時制 -->
  <DateRange v-model="time12Range" :showTime="true" :use24Hour="false" />

  <!-- 不顯示秒數 -->
  <DateRange
    v-model="timeNoSecondsRange"
    :showTime="true"
    :enableSeconds="false"
  />
</template>

輸出格式

ISO 格式輸出

輸出: { "start": "", "end": "" }

ISO 格式輸出(嚴格模式)

輸出: { "start": "", "end": "" }

Javascript Date物件格式

輸出: { "start": "", "end": "" }

物件格式

輸出: { "start": "", "end": "" }

自定義格式輸出

輸出: { "start": "", "end": "" }

vue
<template>
  <!-- ISO 格式 -->
  <DateRange v-model="isoRange" outputType="iso" />

  <!-- ISO 格式(嚴格模式) -->
  <DateRange
    v-model="isoStrictRange"
    outputType="iso"
    :useStrictISO="true"
    :showTime="true"
  />

  <!-- Date物件格式 -->
  <DateRange v-model="jsDateRange" outputType="date" />

  <!-- 物件格式 -->
  <DateRange v-model="objectRange" outputType="object" />

  <!-- 自定義格式 -->
  <DateRange
    v-model="customFormatRange"
    outputType="custom"
    dateFormat="YY/MM/DD"
  />
</template>

Slots 插槽

DateRange 提供多個插槽來自定義快捷選項和錯誤訊息處理。

快捷選項插槽

自定義快捷選項

添加自定義的快捷選項按鈕

Code Example
vue
<template>
  <DateRange v-model="range" :showShortcuts="true">
    <template #shortcuts="{ applyShortcut }">
      <button
        @click="
          applyShortcut({
            label: '本季',
            getValue: () => getCurrentQuarterRange(),
          })
        "
        class="px-3 py-1 text-xs bg-purple-100 text-purple-700 hover:bg-purple-200 rounded-sm transition-colors"
      >
        本季
      </button>
      <button
        @click="
          applyShortcut({
            label: '去年同期',
            getValue: () => getLastYearSamePeriod(),
          })
        "
        class="px-3 py-1 text-xs bg-green-100 text-green-700 hover:bg-green-200 rounded-sm transition-colors"
      >
        去年同期
      </button>
    </template>
  </DateRange>

  <script setup lang="ts">
    // 自定義快捷選項功能
    const getCurrentQuarterRange = () => {
      const now = new Date();
      const quarter = Math.floor(now.getMonth() / 3);
      const startMonth = quarter * 3;
      const start = new Date(now.getFullYear(), startMonth, 1);
      const end = new Date(now.getFullYear(), startMonth + 3, 0);

      return {
        start: {
          year: start.getFullYear(),
          month: start.getMonth() + 1,
          day: start.getDate(),
        },
        end: {
          year: end.getFullYear(),
          month: end.getMonth() + 1,
          day: end.getDate(),
        },
      };
    };

    const getLastYearSamePeriod = () => {
      const now = new Date();
      const lastYear = now.getFullYear() - 1;

      return {
        start: {
          year: lastYear,
          month: now.getMonth() + 1,
          day: 1,
        },
        end: {
          year: lastYear,
          month: now.getMonth() + 1,
          day: now.getDate(),
        },
      };
    };
  </script>
</template>

日曆相關插槽

DateRange 也支援客製化日曆,詳見 DatePicker Slots

錯誤訊息插槽

DateRange 也支援客製化錯誤訊息,詳見 錯誤訊息處理文檔

可用插槽列表

插槽名稱說明Slot Props
shortcuts自定義快捷選項{ applyShortcut, shortcuts, currentRange }
error自定義錯誤訊息顯示{ errors, errorParams, hasErrors }

鍵盤導覽

DateRange 提供完整的鍵盤導航功能:

智能輸入與導航

Tab / Shift+Tab 在開始和結束日期間切換

/ 在日期欄位間切換

Backspace 在空欄位時回到上一個欄位

Enter 完成輸入並驗證

• 完成開始日期後自動聚焦到結束日期

• 完成日期輸入後自動聚焦到時間欄位

範圍驗證

DateRange 提供多種範圍驗證功能:

無效範圍處理

嘗試選擇超過5天的範圍或空範圍查看錯誤提示

自動修正範圍順序

如果結束日期早於開始日期,系統會自動交換

常見驗證規則:

  • 結束日期必須晚於或等於開始日期
  • 範圍天數必須符合 minRangemaxRange 限制
  • 日期必須在 minDatemaxDate 範圍內
  • 兩個日期都不能為空