DatePicker 日期选择器

基于 BrConfigProvider 实现全局主题配置,复用 BrCalendar 核心能力,支持多粒度选择、快捷选择的企业级日期选择器,可无缝集成 BrFormItem。

组件特性

  • 📅 多模式选择:支持单日选择、日期范围选择以及包含时间的选择。
  • 灵活的快捷键:内置并支持自定义丰富的快捷选择项(如”今天”、”近7天”、”本季度”等)。
  • 📝 无缝表单集成:原生对接表单校验体系,自动响应 successerrorwarning 等校验状态。
  • 🎨 高度可定制:基于原子化 CSS 和 BrConfigProvider,可轻松实现全局或局部的主题风格定制。

基础日期选择

最基本的日期选择器,支持清空和禁用特定日期。

<script setup lang="ts">
import { ref } from 'vue'
import { 
  BrDatePicker, 
  BrDatePickerInput, 
  BrDatePickerPopover, 
  BrDatePickerCalendar, 
  BrDatePickerShortcuts 
} from '@breezeui/vue'

const date = ref<Date>()

const shortcuts = [
  { label: 'Today', value: () => new Date() },
  { label: 'Yesterday', value: () => {
      const d = new Date()
      d.setDate(d.getDate() - 1)
      return d
  }}
]
</script>

<template>
  <div class="flex flex-col gap-4 items-center">
    <div class="w-full max-w-sm">
      <BrDatePicker v-model="date" :shortcuts="shortcuts" placeholder="Please enter date">
        <BrDatePickerInput />
        <BrDatePickerPopover>
          <template #shortcuts>
            <BrDatePickerShortcuts />
          </template>
          <BrDatePickerCalendar />
        </BrDatePickerPopover>
      </BrDatePicker>
    </div>
  </div>
</template>

范围选择

带有左侧快捷选择栏的日期范围选择,适用于报表等时间跨度筛选场景。

<script setup lang="ts">
import { ref } from 'vue'
import { 
  BrDatePicker, 
  BrDatePickerInput, 
  BrDatePickerPopover, 
  BrDatePickerCalendar, 
  BrDatePickerShortcuts 
} from '@breezeui/vue'

const range = ref<[Date, Date]>()

const shortcuts = [
  { label: 'Last 7 days', value: () => {
      const end = new Date()
      const start = new Date()
      start.setDate(start.getDate() - 7)
      return [start, end] as [Date, Date]
  }},
  { label: 'Last month', value: () => {
      const end = new Date()
      const start = new Date()
      start.setMonth(start.getMonth() - 1)
      return [start, end] as [Date, Date]
  }}
]
</script>

<template>
  <div class="flex flex-col gap-4 items-center">
    <div class="w-full max-w-sm">
      <BrDatePicker v-model="range" mode="range" :shortcuts="shortcuts" placeholder="Start - End">
        <BrDatePickerInput />
        <BrDatePickerPopover>
          <template #shortcuts>
            <BrDatePickerShortcuts />
          </template>
          <BrDatePickerCalendar />
        </BrDatePickerPopover>
      </BrDatePicker>
    </div>
  </div>
</template>

日期时间选择

附带时分秒选择面板的日期选择器。

<script setup lang="ts">
import { ref } from 'vue'
import { 
  BrDatePicker, 
  BrDatePickerInput, 
  BrDatePickerPopover, 
  BrDatePickerCalendar, 
  BrDatePickerTime 
} from '@breezeui/vue'

const datetime = ref<Date>()
</script>

<template>
  <div class="flex flex-col gap-4 items-center">
    <div class="w-full max-w-sm">
      <BrDatePicker v-model="datetime" show-time placeholder="Select date and time">
        <BrDatePickerInput />
        <BrDatePickerPopover>
          <BrDatePickerCalendar />
          <template #time>
            <BrDatePickerTime />
          </template>
        </BrDatePickerPopover>
      </BrDatePicker>
    </div>
  </div>
</template>

自定义快捷操作

支持自定义快捷操作,无论是单日选择还是范围选择,都可以通过传入 shortcuts 属性来实现复杂的快捷选择逻辑(如:下周一、本季度等)。

<script setup lang="ts">
import { ref } from 'vue'
import { 
  BrDatePicker, 
  BrDatePickerInput, 
  BrDatePickerPopover, 
  BrDatePickerCalendar, 
  BrDatePickerShortcuts 
} from '@breezeui/vue'

const customSingleDate = ref<Date>()
const customRangeDate = ref<[Date, Date]>()

const customSingleShortcuts = [
  { label: 'Next Monday', value: () => {
      const d = new Date()
      // Calculate the date of next Monday
      d.setDate(d.getDate() + ((1 + 7 - d.getDay()) % 7 || 7))
      return d
  }},
  { label: 'End of this month', value: () => {
      const d = new Date()
      // The0day of next month is the last day of this month
      return new Date(d.getFullYear(), d.getMonth() + 1, 0)
  }}
]

const customRangeShortcuts = [
  { label: 'This quarter', value: () => {
      const d = new Date()
      const quarter = Math.floor(d.getMonth() / 3)
      const start = new Date(d.getFullYear(), quarter * 3, 1)
      const end = new Date(d.getFullYear(), quarter * 3 + 3, 0)
      return [start, end] as [Date, Date]
  }},
  { label: 'Past 90 days', value: () => {
      const end = new Date()
      const start = new Date()
      start.setDate(start.getDate() - 90)
      return [start, end] as [Date, Date]
  }}
]
</script>

<template>
  <div class="flex flex-col gap-4 items-center">
    <div class="w-full max-w-sm flex flex-col gap-4">
      <BrDatePicker v-model="customSingleDate" :shortcuts="customSingleShortcuts" placeholder="Select specific date">
        <BrDatePickerInput />
        <BrDatePickerPopover>
          <template #shortcuts>
            <BrDatePickerShortcuts />
          </template>
          <BrDatePickerCalendar />
        </BrDatePickerPopover>
      </BrDatePicker>

      <BrDatePicker v-model="customRangeDate" mode="range" :shortcuts="customRangeShortcuts" placeholder="Select specific range">
        <BrDatePickerInput />
        <BrDatePickerPopover>
          <template #shortcuts>
            <BrDatePickerShortcuts />
          </template>
          <BrDatePickerCalendar />
        </BrDatePickerPopover>
      </BrDatePicker>
    </div>
  </div>
</template>

校验状态

无缝接入表单体系,可以独立配置 validation-state 属性展示成功、错误或警告状态。

<script setup lang="ts">
import { ref } from 'vue'
import { 
  BrDatePicker, 
  BrDatePickerInput, 
  BrDatePickerPopover, 
  BrDatePickerCalendar 
} from '@breezeui/vue'

const date = ref<Date>()
</script>

<template>
  <div class="flex flex-col gap-4 items-center">
    <div class="w-full max-w-sm flex flex-col gap-4">
      <BrDatePicker v-model="date" validation-state="error" placeholder="Error state">
        <BrDatePickerInput />
        <BrDatePickerPopover>
          <BrDatePickerCalendar />
        </BrDatePickerPopover>
      </BrDatePicker>

      <BrDatePicker v-model="date" validation-state="success" placeholder="Success state">
        <BrDatePickerInput />
        <BrDatePickerPopover>
          <BrDatePickerCalendar />
        </BrDatePickerPopover>
      </BrDatePicker>
    </div>
  </div>
</template>

主题定制

通过 BrConfigProvider 全局配置或 Tailwind/UnoCSS 原子化类名控制局部外观,实现深度定制。

<script setup lang="ts">
import { ref } from 'vue'
import { 
  BrConfigProvider,
  BrDatePicker, 
  BrDatePickerInput, 
  BrDatePickerPopover, 
  BrDatePickerCalendar 
} from '@breezeui/vue'

const date1 = ref<Date>()
const date2 = ref<Date>()
</script>

<template>
  <div class="flex flex-col gap-8 items-center">
    <!-- Global config override -->
    <div class="w-full max-w-sm space-y-2">
      <label class="text-sm font-medium">Use BrConfigProvider Override theme color and border radius</label>
      <BrConfigProvider :theme="{ radius: '1rem', primary: '#10b981' }">
        <BrDatePicker v-model="date1" placeholder="Larger border radius,Main color becomes green">
          <BrDatePickerInput />
          <BrDatePickerPopover>
            <BrDatePickerCalendar />
          </BrDatePickerPopover>
        </BrDatePicker>
      </BrConfigProvider>
    </div>

    <!-- Local class name override -->
    <div class="w-full max-w-sm space-y-2">
      <label class="text-sm font-medium">Use Tailwind/UnoCSS Class name local override</label>
      <BrDatePicker v-model="date2" placeholder="Custom Style">
        <BrDatePickerInput class="border-indigo-500 bg-indigo-50/50" />
        <!-- Override popover shadow and background -->
        <BrDatePickerPopover class="shadow-2xl bg-slate-50">
          <BrDatePickerCalendar />
        </BrDatePickerPopover>
      </BrDatePicker>
    </div>
  </div>
</template>

API 说明

BrDatePicker (Root)

属性类型默认值说明
modelValueDate | [Date, Date] | Date[]-绑定的日期值
mode'single' | 'range' | 'multiple''single'日期选择模式
granularity'day' | 'week' | 'month' | 'year''day'日期颗粒度
disabledbooleanfalse是否全量禁用
validationState'default'|'success'|'error'|'warning''default'强制校验状态(通常由 FormItem 自动下发)
shortcutsShortcut[][]快捷选择配置
showTimebooleanfalse是否显示时间选择面板

注:BrDatePickerInputBrDatePickerPopoverBrDatePickerCalendarBrDatePickerShortcuts 共享 Root 上下文,直接按需拼装即可,无需单独传参。