跳转到内容

日期输入 date-field

数据录入组件。三层同源:无头内核给出解剖与状态机,Vue 组件与自定义元素只是它的两层外壳,行为完全一致。

示例

基础用法

三段各是一个可加减的数,整组只占一个 Tab 位,三段填齐才第一次报出值

截止日期
yyyy
mm
dd
当前值:(未填齐)

段序随 locale

同一份标记,locale 换成 en-US 后段序自动排成月日年

zh-CN
2026
07
28
en-US
07
/
28
/
2026

两份值都是 ISO 串:2026-07-28 · 2026-07-28

可填区间

min / max 收窄各段的加减范围,越界的初值只做标注、不被改写

在区间内(2020 – 2030)
2026
07
28
越界(min 2020-01-01)
2019
05
01

禁用与非法

禁用整组退出 Tab 序、隐藏输入不再提交;invalid 只改观感与 aria,不动值

禁用
2026
07
28
只读
2026
07
28
invalid
2026
07
28

形态

variant 只改分段框的底色与描边用法,分段结构与键盘行为都不变

outline
2026
07
28
subtle
2026
07
28
ghost
2026
07
28

语气

tone 决定用哪族颜色,与 variant 正交;这里固定 subtle 形态,只看语气这一轴

brand
2026
07
28
neutral
2026
07
28
success
2026
07
28
warning
2026
07
28
danger
2026
07
28
info
2026
07
28

尺寸

不传 size 即默认档;行高、内边距与字号一起换档,标题也跟着变

sm
2026
07
28
默认
2026
07
28
lg
2026
07
28

精确到分

granularity=minute 在年月日后面接出时、分两段,值随之带上 T 与时间位

发布时间
2026
07
28
 
13
:
45
当前值:2026-07-28T13:45

外部写值与清空

根插槽给出 setValue / clear 与填齐、越界两个判据,按钮照它们摆

取件日期
yyyy
mm
dd
未填齐

值变化事件

value-change 每次带上整份 ISO 串,段位被清掉时它是 null

改一改再看下面
2026
07
28
最近变化:(还没动过)

段位自定义文本

段位插槽给出这一段的类型、取值与焦点状态,离焦后年份只留两位、月份换成中文名

发布日期
26
七月
28
值仍是 ISO 串:2026-07-28

对外值换个写法

组件读写的恒是 ISO 串,宿主用一个双向 computed 换成自己的格式,表单也提交这一份

结算日期
2026
07
28
随表单提交的是:2026/07/28 · 组件里的值是:2026-07-28

产物

自定义元素<xh-date-field>
Vue 组件XhDateFieldControl XhDateFieldHiddenInput XhDateFieldLabel XhDateFieldRoot XhDateFieldSegment
组合式函数useDateField
状态机dateFieldMachine
皮肤@xihan-ui/styles/date-field.css

解剖

部件名即 data-part 属性值,也是皮肤的选择器。加粗的是必备部件,不渲染它组件不工作(Web Components 适配器会在诊断通道上报 wc.missing-part)。

data-scope="date-field"root · label · control · segment · hidden-input

Props

属性类型必填说明
valuestring | null受控值,ISO 串('2026-07-28' / '2026-07-28T13:45');null 表示空。给定即受控。
defaultValuestring | null非受控初值,同样是 ISO 串。
minstring下界,ISO 串。参与各段区间的收窄,并决定 outOfRange。
maxstring上界,ISO 串。
localestringBCP 47 语言标记,决定年月日三段的先后。不给按 en-US(月日年)排。
timeZonestringIANA 时区名,只用来取「今天」:空段上按上下键时从今天的对应位起步。
granularityDateGranularity精度,默认 day(只有年月日三段)。
disabledboolean
readOnlyboolean
invalidboolean
requiredboolean
namestring表单字段名;给了隐藏输入才带 name,ISO 串随表单一并提交。
placeholder{ readonly [K in DateSegmentType]?: string }各段未填时显示的占位串,逐段覆盖内置默认(yyyy / mm / dd / hh / mm / ss)。
translations{ readonly [K in DateSegmentType]?: string }各段的读屏名字,逐段覆盖内置默认。段是 spinbutton,没有名字读屏只念得出一串数字。
variantControlVariant形态:outline / subtle / ghost,决定描边与底色怎么用。
toneTone语气:brand / neutral / success / warning / danger / info,决定聚焦与强调用哪族颜色。
sizeSize尺寸:sm / md / lg。
onValueChange(details: DateFieldValueChangeDetails) => void

状态机

状态idle

事件VALUE.SET · VALUE.CLEAR · SEGMENT.STEP · SEGMENT.TYPE · SEGMENT.CLEAR · SEGMENT.FOCUS · SEGMENT.BLUR · FORM.RESET

判据canEdit

connect API

useDateField 产出的对象。getXxxProps() 铺到对应部件的宿主元素上,其余是可读状态与操作入口。

成员类型说明
valuestring | nullISO 串;段位没填齐时是 null。
valueAsDateDate | null同一个值的原生 Date;空值或算不出来时为 null。按 timeZone 换算。
segmentsDateFieldSegmentState[]逐段投影,文档序即 locale 决定的段序。
completeboolean段位填齐了(value 非 null)。
emptyboolean一段都没填。
outOfRangeboolean填齐了但落在 min/max 之外。
disabledboolean
readOnlyboolean
invalidboolean
focusedSegmentDateSegmentType | null焦点落在哪一段;焦点在组外时为 null。
localestring
granularityDateGranularity
setValue(next: string | null) => void直接写整份值;传 null 等于清空。
clear() => void
getRootProps() => T['element']
getLabelProps() => T['element']标题不是原生 label(段位是 div,不可被 label 标注),点它由连接层代为把焦点送进首段。
getControlProps() => T['element']role=group 的分段容器。
getSegmentProps(props: DateFieldSegmentProps) => T['element']
getHiddenInputProps() => T['input']表单出口:一份 type=hidden 的原生输入,值是 ISO 串。

键盘

规格出处:W3C APG

按键生效条件行为
ArrowUpfocus in a segment, not disabled/readOnly本段加一,到区间上界回绕到下界;空段则落到今天的对应位
ArrowDownfocus in a segment, not disabled/readOnly本段减一,到区间下界回绕到上界;空段则落到今天的对应位
ArrowRightfocus in a segment, not disabled焦点移到下一段(跳过收起的段);已在末段则不动,不回绕
ArrowLeftfocus in a segment, not disabled焦点移到上一段;已在首段则不动,不回绕
Homefocus in a segment, not disabled焦点移到首段
Endfocus in a segment, not disabled焦点移到末段
Backspacefocus in a segment, not disabled/readOnly清掉本段,焦点不动;整份值随之变成 null
0 / 1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 / 9focus in a segment, not disabled/readOnly往本段补一位数字;补满(再补一位必溢出或位数用尽)即自动跳下一段

Released under The MIT License