v0.1.9

DatePicker 日期选择器

引入import { DatePicker } from '@apollo-design/ui';

2026-10-30 当前 API:动态内容使用 #cellRender="{ current, info }"、#panelRender="{ originPanel }"、#extraFooter="{ mode }"、#tagRender="scope";前缀、后缀、清除、区间分隔与预设分别使用同名具名槽。移除旧函数渲染 props、addon、无实际组件的 PurePanel 类型及 notification props;使用 @select/其它原生 emits。@keydown 只收到原生 KeyboardEvent,可直接 preventDefault();支持 v-model:mode。只读输入按 ArrowDown 进入面板,方向键导航,Enter/Space 选值,Escape 返回。DOM refs 在挂载前/卸载后为 null。

输入或选择日期的控件。

视口宽度为 575px 及以下时,日期时间与区间的面板在视口内换行展示,保留全部日期格、时间列与确认操作;两个区间面板均可通过原生键盘选值。较宽视口继续并排展示。

何时使用

  • 当用户需要输入一个日期,可以点击标准输入框,弹出日期面板进行选择;
  • 需要在「日期 / 周 / 月 / 季度 / 年 / 时间」等粒度间切换时,用 picker 指定;
  • 需要选择一段时间范围时,用 RangePicker。

引入

import { DatePicker, RangePicker } from '@apollo-design/ui';

代码演示

加载中…

基本 #

五种选择粒度(日 / 周 / 月 / 季 / 年)由 picker 控制。

加载中…

范围选择器 #

DatePicker.RangePicker(或具名导出的 RangePicker)用于选择一个日期范围。

加载中…

禁用日期 #

disabledDate 按当前面板粒度拿到日期;示例禁用周六/周日,单值与范围版本都生效。

加载中…

上下界 #

minDate / maxDate 同时限制可选日期与面板导航;越界日期以禁用态呈现。

加载中…

日期时间 #

show-time 打开时间面板;format 决定输入框与 change 第二参的文本格式。

加载中…

12 小时制与步长 #

use12Hours 增加上下午列;hourStep / minuteStep 控制时间列可选项的步长。

加载中…

预设范围 #

presets 在面板左侧(范围版)提供常用区间;值可以是 dayjs 实例,也可以是返回实例的函数(懒求值)。

加载中…

受控 #

v-model:value 控制值、v-model:open 控制面板开合;外部按钮可以直接设值、清空或打开面板。

加载中…

格式化 #

format 控制输入框展示与 dateString;范围版可传一个格式给两端,或传二元组分别指定。

加载中…

尺寸、状态与变体 #

size 控制输入框尺寸,status 提供 error/warning 状态,variant 切换 outlined / filled / borderless / underlined。

加载中…

标签与输入属性 #

用 id 与原生 label for 关联输入框,aria-describedby 关联说明。范围选择器使用对象 id 分别标记两端。class/style/data-* 仍作用于选择器根。

Associate native labels with inputs using id and label for, and descriptions using aria-describedby. Object ids identify each range endpoint. class/style/data-* still target the selector root.

加载中…

多选 #

multiple 允许选择多个日期(不支持时间/日期时间);maxTagCount="responsive" 让标签随宽度自适应折叠。

加载中…

自定义单元格 #

cellRender 拿到 current、info.originNode 与面板类型;示例在每 7 天的格子右下角画一个提示圆点,其余仍返回原始节点。

加载中…

需要确认 #

needConfirm 让面板显示“确定”按钮,只有点击确定后值才提交;适合需要二次确认的录入流程。

加载中…

范围日期时间 #

范围选择器同样支持 show-time;两端分别选择日期与时间,format 决定输入框的展示格式。

加载中…

自定义面板 #

panelRender 拿到原始面板节点与当前面板粒度,返回的节点会替换浮层内容;示例在面板外加了一层边框与提示。

加载中…

弹层位置 #

placement 控制浮层相对输入框的落点;空间不足时仍会由触发器自动翻转。

加载中…

允许空值 #

范围选择器用 allowEmpty 指定两端是否允许只选一端;示例要求结束日期必填。

加载中…

组件 Token #

在 DatePicker 根元素上覆写 --apollo-date-picker-* CSS 变量即可定制组件样式,例如 --apollo-date-picker-active-border-color、--apollo-date-picker-hover-border-color、--apollo-date-picker-active-shadow、--apollo-date-picker-input-font-size、--apollo-date-picker-cell-hover-bg 与 --apollo-date-picker-presets-width。打开面板可观察单元格悬浮色。

加载中…

禁用 #

DatePicker 的 disabled 接受布尔值;DatePicker.RangePicker 还支持 [boolean, boolean] 元组,用来只禁用范围中的某一端。示例同时展示完全禁用、带默认值的禁用状态以及单端禁用。

加载中…

受控面板模式 #

mode 用于受控地指定面板粒度(date / month / year)。示例用 RadioGroup 修改 mode,并通过 @panel-change 记录面板切换结果、通过 @change 回显最终选择值。

加载中…

区间内选择 #

@calendar-change 会在范围选择的中间过程触发,携带 info.range 标识当前选的是起点还是终点;disabled-date 的第二个参数 info.from 是已选的起点。示例把结束日期限制在起点前后 7 天内,并实时显示选择进度。

加载中…

起止日期联动 #

两个独立的 DatePicker 通过 disabled-date 互相限制:开始日期不能晚于已选结束日期,结束日期不能早于已选开始日期。@change 回写 value,页面下方实时显示当前范围。

加载中…

语义化结构样式 #

DatePicker 的 classNames / styles 提供 root、prefix、input、suffix 与 popup 语义槽,其中 popup 还可细分为 root / header / body / content / item / footer / container。示例用类名定制输入区与浮层,用 styles 定制输入文字与后缀颜色。

加载中…

自定义后缀图标 #

通过 suffix-icon 传入 VNodeChild 可以替换默认日历图标;传入 null 则完全不渲染后缀图标。示例用 h(CalendarOutlined) 与 h(SmileOutlined) 构造图标节点,并保留第三种「无图标」形态。

加载中…

可切换粒度 #

picker 支持 date、week、month、quarter、year 五种粒度。示例用 RadioGroup 绑定 picker,切换后 DatePicker 的输入格式、面板结构与 @change 返回的 dateString 都会随之变化。

加载中…

时间选择 #

show-time 打开时间面板,format 控制输入框展示格式,disabled-time 返回 { disabledHours, disabledMinutes, disabledSeconds } 来禁用具体档位。示例仅允许选择 09:00 到 18:00,并通过 @change 显示最终值。

加载中…

日期区间 #

DatePicker.RangePicker 同样支持 picker 粒度切换。示例在日期、周、月、年四种粒度间切换,@change 的第二个参数始终是长度为 2 的格式化字符串数组,便于直接展示区间结果。

API

单值 DatePicker

参数 说明 类型 默认值
value(v-model:value) 受控值。null 表示「受控且为空」 DateType | DateType[] | null ——
defaultValue 非受控初始值 同上 ——
picker 选择器粒度 'time' | 'date' | 'week' | 'month' | 'quarter' | 'year' 'date'
mode 面板的当前视图粒度(受控时需自己处理 panelChange) 'time' | 'date' | 'week' | 'month' | 'quarter' | 'year' | 'decade' ——
format 格式。支持字符串 / 数组(多套解析格式)/ 掩码对象 / 函数 DatePickerFormat 由 picker 与语言包推导
showTime 显示时间选择。true 或配置对象(use12Hours / disabledTime / hideDisabledOptions …) boolean | SharedTimeProps ——
showWeek 周选择器下显示周数 boolean ——
showToday 显示「今天」 boolean true
showNow 时间面板显示「此刻」 boolean true
open(v-model:open) 受控开合。undefined = 非受控 boolean ——
defaultOpen 非受控初始开合 boolean false
needConfirm 是否要点「确定」才提交。⚠️ 默认值取决于粒度:time / datetime 为 true,其余 false boolean 见左
multiple 多选 boolean false
order multiple 时按日期排序 boolean true
presets 快捷选项。value 支持函数(懒求值) ValueDate[] ——
disabledDate 不可选日期 (date, info) => boolean ——
minDate / maxDate 可选范围的边界(静态日期,与上游一致) DatePickerDate ——
placeholder 占位符 string 由语言包给出
locale 语言包(与 ConfigProvider 的 locale.DatePicker 深合并) PickerLocale ——
size 尺寸(未传走 ConfigProvider) 'small' | 'medium' | 'middle' | 'large' ——
variant 形态 'outlined' | 'borderless' | 'filled' | 'underlined' 'outlined'
status 校验状态。⚠️ 只加类名,不改 aria-invalid 'error' | 'warning' ——
disabled 禁用 boolean false
inputReadOnly 输入框只读(禁止键入,只能用面板选) boolean false
allowClear 允许清除。传对象可自定义图标 boolean | { clearIcon } true
suffixIcon 后缀图标 VNodeChild 日历图标
prefix 前缀(可放图标或文字) VNodeChild ——
clearIcon 清除图标(deprecated → allowClear.clearIcon) VNodeChild ——
popupClassName 浮层类名(deprecated → classNames.popup) string ——
popupStyle 浮层样式(deprecated → styles.popup) CSSProperties ——
dropdownClassName 同 popupClassName(deprecated) string ——
placement 浮层落点。未传时按方向取默认(LTR bottomLeft / RTL bottomRight) 'bottomLeft' | 'bottomRight' | 'topLeft' | 'topRight' ——
popupAlign 浮层的对齐偏移 AlignType ——
builtinPlacements 自定义落点表 Record<string, AlignType> 内置四个
getPopupContainer 浮层挂载容器 (node) => HTMLElement document.body
transitionName 浮层动效名 string ${rootPrefixCls}-slide-up
required 原生 required(透传 input[required] 与 aria-required) boolean ——
name / autoComplete / id 绑定原生 input;id 可与 label for 关联 string autoComplete: 'off'
tabIndex / tabindex 原生输入框的 Tab 顺序;tabindex 可作为 Vue attr 传入 number ——
autoFocus 挂载时聚焦第一个未禁用的输入框 boolean false
prefixCls 类名前缀。⚠️ 默认是 apollo-picker(不是 apollo-date-picker) string ——
class / style 根节点原生 attrs(替代上游 className / rootClassName / style) string | array | object / CSSProperties ——
classNames / styles 语义化类名 / 样式(4 个平铺 + 7 个嵌套 popup)。popup 允许 string(= popup.root)。classNames.root / styles.root 落选择器根元素(与原生 class / style 合并,原生胜) DatePickerSemanticAllType ——

顶层时间配置

上游 PickerProps extends Omit<SharedTimeProps, 'format' | 'defaultValue'>(SinglePicker.d.ts)⇒ 下面这组键是顶层 prop(不必塞进 showTime),与 showTime 在 getTimeProps 内部合并 (showTime 里的同名键胜)。它们对日期面板与时间面板都生效。

Prop 说明 类型 默认
use12Hours 12 小时制(时间列多一列上午下午) boolean ——
showHour / showMinute / showSecond / showMillisecond 显式开关某一列 boolean 全部按格式推导
hourStep / minuteStep / secondStep / millisecondStep 列内档位步长 number 1 / 1 / 1 / 100
hideDisabledOptions 为真时跳过禁用档位(而不是渲染成禁用态) boolean false
disabledTime 按天给出禁用的档位(disabledHours 等三个 legacy 键见「兼容性说明」) (date) => DisabledTimes ——
changeOnScroll 时间列滚动时立即改值 boolean false
defaultOpenValue 无值时面板的锚定时刻(不写入值;点「确定」才会落值) DatePickerDate ——

事件

事件 说明 载荷
update:value v-model:value 通道 (date)
change 值变化(与 update:value 同时发) (date, dateString)
calendarChange 面板选中过程中每次变化(未提交也发) (date, dateString, info),info.range / info.from
ok 点「确定」 (date)
openChange 浮层开合 (open, config?)
update:open v-model:open 通道 (open)
pickerValueChange 面板浏览值变化 (date, info),info.source 为 'reset' | 'panel'
update:pickerValue v-model:pickerValue 通道 (date)
panelChange 面板粒度变化 (value, mode)
clear 点清除按钮 ——
focus / blur 焦点进出 (event, info)
invalid 键入值非法 (invalid)
submit 表单提交 (event)
keydown 按键(deprecated onKeyDown 的通道) (event: KeyboardEvent)

Slots

插槽 说明 参数
panelRender 替代 panelRender prop { originPanel }
extraFooter 替代 renderExtraFooter prop { mode }
cellRender 替代 cellRender prop { current, info }

Expose

方法 说明 类型
focus 聚焦输入框 (options?: FocusOptions) => void
blur 失焦 () => void
nativeElement 根节点 HTMLDivElement

RangePicker(与单值的差异)

参数 差异
value / defaultValue 元组 [start, end]。⚠️ null 与 undefined 语义不同:null = 「清空该端」,undefined = 「尚未选」
placeholder 元组 [string, string]
id string | { start?: string; end?: string };字符串只绑定起点,对象分别绑定两端,不生成额外 id
separator 两端之间的分隔符。默认分隔符带 aria-hidden;自定义的会去掉它
allowEmpty 允许某一端为空(boolean 或两端元组)
disabled boolean 或两端元组。⚠️ 根类名 -disabled 只在两端都禁时加
showTime boolean | RangeTimeProps(disabledTime 多 range / info 两个参数)
presets RangeValueDate[]
onSelect deprecated,且只在 picker === 'time' 时生效
focus 签名不同:(index?) => void,可指定聚焦哪一端
startInput / endInput 两个原生输入框

原生属性落点

class、style、data-* 和原生鼠标事件留在选择器根。id、tabIndex / tabindex、name、required、autoComplete、autoFocus 以及 aria-* 绑定实际输入框;范围选择器的共享属性应用到两端。aria-invalid 由内部输入校验维护,aria-required 默认随 required,可显式覆盖。受控值、输入事件和 ref 由组件维护。

修复 F01 后,原先根上的输入 ARIA 和 Tab 顺序移到 input;请将针对这些属性的 DOM 查询指向 input。范围两端需要不同标签时使用对象 id 与两个 label for。

Theme

组件级 Token —— 45 个,全部落成 CSS 变量 --apollo-date-picker-*。

下表是 node tests/visual/debug/extract-date-picker-css.mjs --tokens 的实测值 (antd 6.6.4 默认主题),不是推算。

Token 默认值
activeBg #ffffff
activeBorderColor #1677ff
activeShadow 0 0 0 2px rgba(5,145,255,0.1)
addonBg rgba(0,0,0,0.02)
arrowPath path('M 0 8 A 4 4 0 0 0 2.828…')
arrowPolygon polygon(1.6568542494923806px 100%, 50% 1.6568542494923806px, …)
arrowShadowWidth 8.970562748477143px
cellActiveWithRangeBg #e6f4ff
cellBgDisabled rgba(0,0,0,0.04)
cellHeight 24px
cellHoverBg rgba(0,0,0,0.04)
cellHoverWithRangeBg #cbe0fd
cellRangeBorderColor #82b4f9
cellWidth 36px
errorActiveShadow 0 0 0 2px rgba(255,38,5,0.06)
hoverBg #ffffff
hoverBorderColor #4096ff
inputFontSize 14px
inputFontSizeLG 16px
inputFontSizeSM 14px
lineWidthFocus 1px
multipleItemBg rgba(0,0,0,0.06)
multipleItemBorderColor transparent
multipleItemBorderColorDisabled transparent
multipleItemColorDisabled rgba(0,0,0,0.25)
multipleItemHeight 24px
multipleItemHeightLG 32px
multipleItemHeightSM 16px
multipleSelectorBgDisabled rgba(0,0,0,0.04)
paddingBlock 4px
paddingBlockLG 7px
paddingBlockSM 0px
paddingInline 11px
paddingInlineLG 11px
paddingInlineSM 7px
presetsMaxWidth 200px
presetsWidth 120px
textHeight 40px
timeCellHeight 28px
timeColumnHeight 224px
timeColumnWidth 56px
warningActiveShadow 0 0 0 2px rgba(255,215,5,0.1)
withoutTimeCellHeight 66px
zIndexPopup 1050
INTERNAL_FIXED_ITEM_MARGIN 2px —— 变量名是 --apollo-date-picker-internal_fixed_item_margin(带下划线)

⚠️ 另有一个规则内声明的变量 --apollo-date-picker-affix-color(默认 inherit, 错误 / 警告态被覆盖)—— 它不在 prepareComponentToken 的返回值里,而是写在 样式规则内部。详见 README §4。

设计说明

类名前缀与 CSS 变量命名空间不同名

默认类名是 apollo-picker(上游 getPrefixCls('picker', …) 传的是字面量 'picker'), 而 CSS 变量是 --apollo-date-picker-*(由组件名 DatePicker 派生)。 两者不同名是上游行为,不是笔误 —— 自定义主题时别改错。

time-picker 与本组件共用一套样式

ant-picker 前缀被 date-picker 与 time-picker 共用(上游刻意如此)⇒ 本组件的样式里 含 time-picker 的规则。那是对的(同一组件族)。

静态 CSS 的一处已知差异

构建期解析出来的常量(padding 算式、activeShadow 模板串、cellHoverWithRangeBg 的 lighten(35) 等)在静态 CSS 里被内联成字面值 ⇒ 不随主色变化 (上游 cssinjs 会在运行时重算)。这是本仓「静态 CSS + CSS 变量」架构的固有差异, 不是 bug;影响面由 L6 的主题矩阵钉住。

Powered by Vue 3 + ViteApollo Design · Vue NativeGitHub