Ant Design DatePicker 组件完全指南:五种选择模式、RangePicker、国际化与进阶配置实战解析
DatePicker 是 Ant Design 中用于“输入/选择日期”的核心数据录入组件。本文以 components/date-picker/index.en-US.md 为骨架,结合组件源码(generatePicker 工厂、locale 实现等)系统讲解:DatePicker 的适用场景、DatePicker / RangePicker / picker=year|quarter|month|week 五种形态、共享与专属 API 全表、国际化配置、format 类型、语义化 DOM、Design Token 以及高频 FAQ。读完本文,你将掌握该组件的完整配置面,并理解其“generateConfig 驱动、可扩展日期库”的底层架构。
适用场景:什么时候使用 DatePicker
文档明确给出其适用边界——当需要用户点击输入框、从弹出的日历面板中选择一个日期时,使用 DatePicker。它同时覆盖以下诉求:
- 纯日期选择(date)、周选择(week)、月选择(month)、季度选择(quarter)、年选择(year),以及起止成对的 RangePicker 范围选择;
- 在
showTime开启后支持“日期 + 时间”复合录入; - 通过
presets提供“最近 7 天”之类的快捷范围; - 通过
disabledDate/disabledTime/minDate/maxDate精确限制可选范围。
组件家族与底层架构:五种 Picker 与 RangePicker 是如何被“生产”出来的
按官方文档,仓库中共有五种(实为六种形态)选择器:
DatePickerDatePicker[picker="month"]DatePicker[picker="week"]DatePicker[picker="year"]DatePicker[picker="quarter"](4.1.0 起新增)RangePicker
最小使用方式如下(与 demo/basic.tsx 一致),一段代码即可体验全部 picker 形态:
import React from 'react';
import type { DatePickerProps } from 'antd';
import { DatePicker, Flex } from 'antd';
const onChange: DatePickerProps['onChange'] = (date, dateString) => {
console.log(date, dateString);
};
const Demo: React.FC = () => (
<Flex gap="small" justify="flex-start" align="flex-start" vertical>
<DatePicker onChange={onChange} />
<DatePicker onChange={onChange} picker="week" />
<DatePicker onChange={onChange} picker="month" />
<DatePicker onChange={onChange} picker="quarter" />
<DatePicker onChange={onChange} picker="year" />
</Flex>
);
export default Demo;
值得说明的是,generatePicker/generateSinglePicker.tsx 会一次性产出 DatePicker / WeekPicker / MonthPicker / YearPicker / QuarterPicker(旧版还含 TimePicker),而 generatePicker/generateRangePicker.tsx 负责生成 RangePicker。generatePicker/index.tsx 中的 generatePicker 函数再把它们聚合挂载到同一对象上:
const generatePicker = <DateType extends AnyObject = AnyObject>(
generateConfig: GenerateConfig<DateType>,
) => {
const { DatePicker, WeekPicker, MonthPicker, YearPicker, TimePicker, QuarterPicker } =
generateSinglePicker(generateConfig);
const RangePicker = generateRangePicker(generateConfig);
// ...
MergedDatePicker.WeekPicker = WeekPicker;
MergedDatePicker.MonthPicker = MonthPicker;
MergedDatePicker.YearPicker = YearPicker;
MergedDatePicker.RangePicker = RangePicker;
// ...
return MergedDatePicker;
};
而 DatePicker 的真正入口 index.tsx 只做了一件事:把 @rc-component/picker 的 dayjs 生成配置注入工厂,产出最终组件:
const DatePicker = generatePicker<Dayjs>(dayjsGenerateConfig);
由此可推断出它的架构核心:Picker 的上层能力(面板、popup、交互)与具体日期库解耦,通过 GenerateConfig 抽象日期的加减、格式化、比较等操作。这也是 FAQ 中“如何接入自定义日期库”能被支持的底层原因——相关指南同样收录在仓库 docs/react 目录下。此外 index.tsx 还为组件挂载了仅供内部调试的面板与 generatePicker 静态方法,这也是 demo 中 _InternalPanelDoNotUseOrYouWillBeFired 类调试示例存在的原因。
国际化:从全局入口到单个组件的语言配置
文档强调:DatePicker 默认语言为 en-US。若需其他语言,优先在应用入口使用 Ant Design 提供的国际化组件整体配置(ConfigProvider 文档见 components/config-provider/index.en-US.md);若只是单个组件有特殊语言需求,则使用 locale 属性。
全局语言配置(推荐)
官方给出的标准做法如下——除了给 <ConfigProvider> 传入 locale,还要求额外引入对应的 dayjs locale 文件并调用 dayjs.locale(),否则范围选择器中的月份等文案不会随语言切换:
// 默认语言为 en-US;如需其他语言,在入口文件中全局设置 locale
// 务必同时引入对应的 dayjs locale 文件,否则 range picker 等文本不会随 locale 改变
import locale from 'antd/locale/zh_CN';
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
dayjs.locale('zh-cn');
<ConfigProvider locale={locale}>
<DatePicker defaultValue={dayjs('2015-01-01', 'YYYY-MM-DD')} />
</ConfigProvider>;
Next.js App Router 注意事项
文档特别给出了警告:使用 Next.js App Router 时,务必在导入 Day.js locale 文件前加上 'use client'。原因是所有 Ant Design 组件仅在客户端运行,在 RSC(React Server Component)中直接导入 locale 文件不会生效。
单组件 locale 与 placeholder 的来源
仓库中的多语言文件位于 components/date-picker/locale,其结构基准是 locale/example.json。一个语言包由 lang(面板文案)与 timePickerLocale(时间面板文案)两部分组成,例如:
{
"lang": {
"locale": "en_US",
"placeholder": "Select date",
"rangePlaceholder": ["Start date", "End date"],
"today": "Today",
"now": "Now",
"ok": "OK",
"clear": "Clear",
"yearFormat": "YYYY",
"fieldDateFormat": "M/D/YYYY",
"cellDateFormat": "D",
"monthBeforeYear": true,
"shortWeekDays": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
"shortMonths": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
},
"timePickerLocale": {
"placeholder": "Select time"
}
}
具体到 placeholder 的解析逻辑,可参考 date-picker/util.ts:getPlaceholder / getRangePlaceholder 会优先返回用户自定义 placeholder,否则按 picker 类型分别回退到 lang.yearPlaceholder / quarterPlaceholder / monthPlaceholder / weekPlaceholder、timePickerLocale.placeholder 或最通用的 lang.placeholder,RangePicker 则对应 rangeYearPlaceholder、rangePlaceholder 等成对文案。
为什么全局 dayjs.locale() 不生效?
DatePicker 组件自身默认携带 en 语言。若全局 dayjs locale 未生效,应改用 DatePicker 的 locale 属性或 ConfigProvider 的 locale(部分日期相关组件的语言失效问题,可参阅仓库 docs/react 目录下的 FAQ 说明)。
Common API:DatePicker 与 RangePicker 共享属性全表
以下为文档给出的、两种 Picker 共用的完整属性表:
| Property | Description | Type | Default | Version | Global Config |
|---|---|---|---|---|---|
| allowClear | 自定义清除按钮 | boolean | { clearIcon?: ReactNode } | true | 5.8.0 起支持对象类型 | 6.4.0 |
是否显示边框样式,请改用 variant |
boolean | true | - | × | |
| className | 选择器类名 | string | - | - | DatePicker: 5.7.0, RangePicker: 5.11.0 |
| classNames | 为组件内部各语义结构自定义 class,支持对象或函数 | Record<SemanticDOM, string> | (info: { props }) => Record<SemanticDOM, string> | - | - | DatePicker: 5.25.0, RangePicker: 5.25.0 |
| dateRender | 日期单元格自定义渲染函数,>= 5.4.0 请改用 cellRender |
function(currentDate: dayjs, today: dayjs) => React.ReactNode | - | < 5.4.0 | × |
| cellRender | 选择器单元格自定义渲染 | (current, info: { originNode, today, range?: 'start' | 'end', type: PanelMode, locale?, subType? }) => ReactNode | - | 5.4.0 | × |
| components | 自定义面板 | Record<Panel | 'input', React.ComponentType> | - | 5.14.0 | × |
| defaultOpen | 面板初始展开状态 | boolean | - | - | × |
| disabled | 是否禁用 | boolean | false | - | × |
| disabledDate | 指定不可选择的日期 | (currentDate, info: { from?, type: Picker }) => boolean | - | info: 5.14.0 | × |
弹出日历 className,请改用 classNames.popup.root |
string | - | - | × | |
| format | 日期格式,数组时支持多格式匹配、以第一个为展示格式,语法参考 dayjs 的 format 能力 | formatType | rc-picker 内置默认值 | - | × |
| order | multiple 或范围选择时是否自动排序 | boolean | true | 5.14.0 | × |
弹出层 className,改用 classNames.popup.root |
string | - | 4.23.0 | × | |
| preserveInvalidOnBlur | 失焦时不清空非法输入 | boolean | false | 5.14.0 | × |
| getPopupContainer | 浮层挂载容器,默认在 body 下新建 div |
function(trigger) | - | - | × |
| inputReadOnly | 设置 input 的 readonly(避免触屏虚拟键盘) |
boolean | false | - | × |
| locale | 语言配置对象 | object | example.json 默认值 | - | × |
| minDate | 最小可选日期,同时限制面板可切换范围 | dayjs | - | 5.14.0 | × |
| maxDate | 最大可选日期,同时限制面板可切换范围 | dayjs | - | 5.14.0 | × |
| mode | 面板模式 | time | date | month | year | decade | - | - | × |
| needConfirm | 是否需要点击确认按钮才触发值变更,multiple 时默认 false |
boolean | - | 5.14.0 | × |
| nextIcon | 自定义 next 图标 | ReactNode | - | 4.17.0 | × |
| open | 面板展开状态(受控) | boolean | - | - | × |
| panelRender | 自定义面板渲染 | (panelNode) => ReactNode | - | 4.5.0 | × |
| picker | 设置选择器类型 | date | week | month | quarter | year | date | quarter: 4.1.0 | × |
| placeholder | 日期输入框占位符 | string | [string, string] | - | - | × |
| placement | 弹层弹出方位 | bottomLeft | bottomRight | topLeft | topRight | bottomLeft | - | × |
弹层样式,改用 styles.popup.root |
CSSProperties | {} | - | × | |
| prefix | 自定义前缀 | ReactNode | - | 5.22.0 | × |
| presets | 快捷选择范围;5.8.0 起 value 支持回调函数 | { label, value: Dayjs | (() => Dayjs) }[] | - | - | × |
| prevIcon | 自定义 prev 图标 | ReactNode | - | 4.17.0 | × |
| previewValue | 悬停候选日期时输入框值是否临时变化 | false | hover | hover | 6.0.0 | × |
| size | 输入框尺寸;large / small 高度分别为 40px / 24px,默认 32px | large | medium | small | - | - | × |
| status | 校验状态 | 'error' | 'warning' | - | 4.19.0 | × |
| style | 输入框样式 | CSSProperties | {} | - | DatePicker: 5.7.0, RangePicker: 5.11.0 |
| styles | 为内部各语义结构自定义内联样式,支持对象或函数 | Record<SemanticDOM, CSSProperties> | (info) => Record<SemanticDOM, CSSProperties> | - | - | DatePicker: 5.25.0, RangePicker: 5.25.0 |
| suffixIcon | 自定义后缀图标 | ReactNode | - | - | DatePicker: 6.3.0, RangePicker: 6.4.0 |
| superNextIcon | 自定义 super next 图标 | ReactNode | - | 4.17.0 | × |
| superPrevIcon | 自定义 super prev 图标 | ReactNode | - | 4.17.0 | × |
| clearIcon | (仅支持全局配置)自定义清除图标 | ReactNode | - | × | 6.4.0 |
| variant | 选择器变体 | outlined | borderless | filled | underlined | outlined | 5.13.0 | underlined: 5.24.0 | DatePicker: 5.19.0, RangePicker: 5.19.0 |
| onClear | 点击清除按钮的回调 | () => void | - | 6.5.0 | × |
| onOpenChange | 弹层打开/关闭回调 | function(open) | - | - | × |
| onPanelChange | 面板模式切换回调 | function(value, mode) | - | - | × |
选中日期回调,请改用 onCalendarChange |
function(value) | - | - | × |
关键共享属性源码级解读
- allowClear / clearIcon:5.8.0 起支持对象形式(自定义清除图标),其合并逻辑位于 util.ts 的
useIcons——当allowClear === false时返回 false,否则把全局clearIcon与对象配置合并后再传给底层。 - 废弃属性迁移:
bordered → variant;dropdownClassName / popupClassName → classNames.popup.root;popupStyle → styles.popup.root。这一点在 generatePicker/interface.ts 的注释中均有明确标注,新代码应直接使用variant与语义化 classNames/styles。 - format / formatType:支持字符串、函数、数组及对象(
{ format, type: 'mask' })四类写法,详见下文 formatType 小节。若传入字符串数组,输入框手动录入时任意命中一种格式即可解析,展示则取数组第一项。在 markdown 文档的行内展示语法之外,实际配置示例可参考 demo/format.tsx。 - multiple 与类型泛型:
multiple一旦开启,value / defaultValue会从单个Dayjs变为Dayjs[]。该类型映射定义在 interface.ts 的PickerPropsWithMultiple中,因此 TS 侧写法为DatePickerProps<Dayjs, true>,多个日期会以 Tag 形式展示;此时若再加needConfirm则默认关闭确认模式。可对照 demo/multiple.tsx 与 demo/needConfirm.tsx。 - minDate / maxDate:除限制可选范围外,还会限制面板可切换的月份范围。典型用法见 demo/date-range.tsx:
<DatePicker
defaultValue={dayjs('2019-09-03', dateFormat)}
minDate={dayjs('2019-08-01', dateFormat)}
maxDate={dayjs('2020-10-31', dateFormat)}
/>
- presets:5.8.0 起
value既可以是Dayjs,也可以是返回Dayjs的函数,从而支持“当前时刻”这类动态范围,见 demo/preset-ranges.tsx:
<RangePicker
presets={[
{
label: <span aria-label="Current Time to End of Day">Now ~ EOD</span>,
value: () => [dayjs(), dayjs().endOf('day')], // 5.8.0+ 支持函数
},
{ label: 'Last 7 Days', value: [dayjs().add(-7, 'd'), dayjs()] },
]}
showTime
format="YYYY/MM/DD HH:mm:ss"
/>
- onClear / onOpenChange / onPanelChange / onSelect 弃用:值改变类事件在单选择器用
onChange,范围选择器细粒度事件用onCalendarChange(onSelect已废弃,请勿再使用)。
通用方法(Common Methods)
两种 Picker 均通过 ref 暴露以下命令式方法:
| Name | Description |
|---|---|
| blur() | 移除焦点 |
| focus() | 获取焦点 |
单日期选择器:DatePicker 专属 API
| Property | Description | Type | Default | Version |
|---|---|---|---|---|
| defaultPickerValue | 默认面板日期,面板打开时会重置 | dayjs | - | 5.14.0 |
| defaultValue | 默认选中日期;若范围选择中起止其一为空,则区间为开区间 | dayjs | - | - |
| disabledTime | 指定不可选择的时间 | function(date) | - | - |
| format | 日期格式,语法参考 dayjs format | formatType | YYYY-MM-DD |
- |
| multiple | 开启多选;不支持与 showTime 同时使用 |
boolean | false | 5.14.0 |
| pickerValue | 面板日期;用于受控切换面板,配合 onPanelChange |
dayjs | - | 5.14.0 |
| renderExtraFooter | 在面板内渲染额外底部 | (mode) => ReactNode | - | - |
| showNow | 显示“此刻”快捷入口 | boolean | - | 4.4.0 |
| showTime | 提供额外的时间选择 | object | boolean | TimePicker 配置 | - |
已废弃,改用 showTime.defaultOpenValue |
dayjs | dayjs() | 5.27.3 | |
| showTime.defaultOpenValue | 设置选中日期的默认时间 | dayjs | dayjs() | - |
| showWeek | 在 DatePicker 中展示周信息 | boolean | false | 5.14.0 |
| value | 受控值 | dayjs | - | - |
| onChange | 选中时间变化回调 | function(date: dayjs | null, dateString: string | null) | - | - |
| onOk | 点击确定按钮的回调 | function() | - | - |
| onPanelChange | 面板切换回调 | function(value, mode) | - | - |
时间 + 日期组合的典型示例(demo/time.tsx):
<DatePicker
showTime
onChange={(value, dateString) => {
console.log('Selected Time: ', value);
console.log('Formatted Selected Time: ', dateString);
}}
onOk={onOk}
/>
<RangePicker
showTime={{ format: 'HH:mm' }}
format="YYYY-MM-DD HH:mm"
onChange={(value, dateString) => { /* ... */ }}
onOk={onOk}
/>
DatePicker[picker="year"]
| Property | Description | Type | Default | Version |
|---|---|---|---|---|
| defaultValue | 默认日期 | dayjs | - | - |
| format | 日期格式 | formatType | YYYY |
- |
| multiple | 多选 | boolean | false | 5.14.0 |
| renderExtraFooter | 渲染额外底部 | () => ReactNode | - | - |
| tagRender | 自定义 Tag 渲染(仅在 multiple 时生效) |
(props) => ReactNode | - | 6.4.0 |
| value | 受控值 | dayjs | - | - |
| onChange | 值变化回调 | function(date, dateString) | - | - |
DatePicker[picker="quarter"]
4.1.0 起提供。
| Property | Description | Type | Default | Version |
|---|---|---|---|---|
| defaultValue | 默认日期 | dayjs | - | - |
| format | 日期格式 | formatType | YYYY-\QQ |
- |
| multiple | 多选 | boolean | false | 5.14.0 |
| renderExtraFooter | 渲染额外底部 | () => ReactNode | - | - |
| tagRender | 自定义 Tag 渲染(仅 multiple 时生效) |
(props) => ReactNode | - | 6.4.0 |
| value | 受控值 | dayjs | - | - |
| onChange | 值变化回调 | function(date, dateString) | - | - |
DatePicker[picker="month"]
| Property | Description | Type | Default | Version |
|---|---|---|---|---|
| defaultValue | 默认日期 | dayjs | - | - |
| format | 日期格式 | formatType | YYYY-MM |
- |
| multiple | 多选 | boolean | false | 5.14.0 |
| renderExtraFooter | 渲染额外底部 | () => ReactNode | - | - |
| tagRender | 自定义 Tag 渲染(仅 multiple 时生效) |
(props) => ReactNode | - | 6.4.0 |
| value | 受控值 | dayjs | - | - |
| onChange | 值变化回调 | function(date, dateString) | - | - |
DatePicker[picker="week"]
| Property | Description | Type | Default | Version |
|---|---|---|---|---|
| defaultValue | 默认日期 | dayjs | - | - |
| format | 日期格式 | formatType | YYYY-wo |
- |
| multiple | 多选 | boolean | false | 5.14.0 |
| renderExtraFooter | 渲染额外底部 | (mode) => ReactNode | - | - |
| tagRender | 自定义 Tag 渲染(仅 multiple 时生效) |
(props) => ReactNode | - | 6.4.0 |
| value | 受控值 | dayjs | - | - |
| onChange | 值变化回调 | function(date, dateString) | - | - |
| showWeek | 展示周信息 | boolean | true | 5.14.0 |
由此可看到,week 默认即展示周信息(showWeek: true),且默认格式为 YYYY-wo(ISO 周号)。
RangePicker 专属 API
| Property | Description | Type | Default | Version | Global Config |
|---|---|---|---|---|---|
| allowEmpty | 允许开始或结束输入为空 | [boolean, boolean] | [false, false] | - | × |
| cellRender | 单元格自定义渲染 | (current, info: { ..., range?: 'start' | 'end', ... }) => ReactNode | - | 5.4.0 | × |
| dateRender | 日期单元格自定义渲染,>= 5.4.0 改用 cellRender |
function(currentDate, today) => ReactNode | - | < 5.4.0 | × |
| defaultPickerValue | 默认面板日期,打开面板时重置 | [dayjs, dayjs] | - | 5.14.0 | × |
| defaultValue | 默认日期范围 | [dayjs, dayjs] | - | - | × |
| disabled | 分别禁用开始/结束 | [boolean, boolean] | - | - | × |
| disabledTime | 指定不可选择的时间 | function(date, partial: 'start' | 'end', info: { from? }) | - | info.from: 5.17.0 | × |
| format | 日期格式 | formatType | YYYY-MM-DD HH:mm:ss |
- | × |
| id | 配置两个输入框的 id | { start?: string, end?: string } | - | 5.14.0 | × |
| pickerValue | 受控面板日期,配合 onPanelChange |
[dayjs, dayjs] | - | 5.14.0 | × |
| presets | 快捷范围(数组形式的 Dayjs 或函数) | { label, value: [(Dayjs | (() => Dayjs)), ...] }[] | - | - | × |
| renderExtraFooter | 渲染额外底部 | () => ReactNode | - | - | × |
| separator | 两个输入框之间的分隔符 | ReactNode | <SwapRightOutlined /> |
6.3.0 | × |
| showTime | 附加时间选择 | object | boolean | TimePicker 配置 | - | × |
废弃,改用 showTime.defaultOpenValue |
[dayjs, dayjs] | [dayjs(), dayjs()] | 5.27.3 | × | |
| showTime.defaultOpenValue | 默认起止时间 | [dayjs, dayjs] | [dayjs(), dayjs()] | - | × |
| value | 受控日期范围 | [dayjs, dayjs] | - | - | × |
| onCalendarChange | 起止任一改变时触发;info 自 4.4.0 起提供 | function(dates, dateStrings, info: { range }) | - | - | × |
| onChange | 选中时间变化回调 | function(dates | null, dateStrings | null) | - | - | × |
| onFocus | 聚焦时触发 | function(event, { range: 'start' | 'end' }) | - | range: 5.14.0 | × |
| onBlur | 失焦时触发 | function(event, { range: 'start' | 'end' }) | - | range: 5.14.0 | × |
要点补充:
onFocus/onBlur通过info.range告诉你焦点落在开始还是结束输入框;id属性则为两个输入框分别指定 DOM id(参考 demo/range-picker.tsx 中 start/end 写法)。disabledTime的第二个参数partial区分是 start 还是 end 面板,从而可以实现“结束时间不允许早于开始时间”等业务规则,示例见 demo/disabled-date.tsx。separator自 6.3.0 起可自定义,默认是交换图标<SwapRightOutlined />。
范围禁用示例(Disabled Date & Time)
<RangePicker
disabledDate={disabledDate}
disabledTime={disabledRangeTime}
showTime={{
hideDisabledOptions: true,
defaultOpenValue: [dayjs('00:00:00', 'HH:mm:ss'), dayjs('11:59:59', 'HH:mm:ss')],
}}
format="YYYY-MM-DD HH:mm:ss"
/>
其中 disabledDate 使用“当天结束时刻”做比较来禁止今天及之前日期;disabledRangeTime 依据 type === 'start' 返回不同的禁用小时/分钟/秒集合。
formatType:四种可用的格式写法
文档给出了 format 属性的完整 TypeScript 定义:
import type { Dayjs } from 'dayjs';
type Generic = string;
type GenericFn = (value: Dayjs) => string;
export type FormatType =
| Generic
| GenericFn
| Array<Generic | GenericFn>
| {
format: string;
type?: 'mask';
};
注意:对象写法中的 type: 'mask' 自 5.14.0 起加入,用于“掩码输入/显示”类格式;数组写法则表示多格式匹配(录入时任一命中即可,展示取第一项)。综合示例参考 demo/format.tsx 与 demo/mask.tsx:
const dateFormatList = ['DD/MM/YYYY', 'DD/MM/YY', 'DD-MM-YYYY', 'DD-MM-YY'];
// 函数式格式:允许完全自定义展示文本
const customFormat: DatePickerProps['format'] = (value) =>
`custom format: ${value.format(dateFormat)}`;
const customWeekStartEndFormat: DatePickerProps['format'] = (value) =>
`${dayjs(value).startOf('week').format('MM/DD')} ~ ${dayjs(value).endOf('week').format('MM/DD')}`;
<DatePicker defaultValue={dayjs('01/01/2015', dateFormatList[0])} format={dateFormatList} />
<DatePicker defaultValue={dayjs()} format={customWeekStartEndFormat} picker="week" />
<DatePicker defaultValue={dayjs('2015/01/01', dateFormat)} format={customFormat} />
Semantic DOM:语义化结构与精细化样式定制
组件内部被拆分为可独立命名的语义节点。文档中对应的结构示例位于 demo/_semantic.tsx。从类型定义 generatePicker/interface.ts 可以看到完整的语义层级:
- 外层:
root、prefix、input、suffix; - 弹层
popup:可细分为root、header、body、content、item、footer、container。
因此你可以用两种方式做“像素级”定制:
<DatePicker
className="my-picker"
classNames={{ input: 'custom-input', popup: { body: 'custom-body' } }}
styles={{ input: { color: 'red' }, popup: { root: { boxShadow: 'none' } } }}
/>
classNames / styles 均同时支持对象与函数两种形式(函数接收 { props } 以便按属性动态计算)。自 6.0.0 起新增的语义化类名样式(custom semantic dom styling)示例见 demo/style-class.tsx。另外 suffixIcon、prefix、status、variant、size、placement 等外观/布局类属性都有对应演示(demo/suffix.tsx、demo/status.tsx、demo/variant.tsx、demo/size.tsx、demo/placement.tsx)。
Design Token:通过主题 Token 统一定制样式变量
官方文档中的 “Design Token” 区块由 <ComponentTokenTable component="DatePicker" /> 动态渲染,列出 DatePicker 支持覆盖的全部组件级 Token。从源码结构看,这些 Token 定义与各样式入口位于 components/date-picker/style(含 index.ts、panel.ts、multiple.ts、variants.ts、util.ts 与定义 Token 的 token.ts)。实际覆盖通常通过 ConfigProvider 的 theme.components.DatePicker 完成;组件 Token 演示见 demo/component-token.tsx。
示例索引:官方 Demo 全覆盖
下表整理了官方文档示例(md 与 tsx 一一对应,均在 components/date-picker/demo 下):
- basic:五种 picker 基础用法
- range-picker:RangePicker 各形态
- multiple(5.14.0):多选与尺寸联动
- needConfirm(5.14.0):确认后才提交
- switchable:动态切换 picker 类型
- format:自定义格式与多格式解析
- time:时间选择
- mask(5.14.0):掩码格式
- date-range(5.14.0):minDate / maxDate 限制
- disabled:禁用
- disabled-date:禁用日期与时间
- allow-empty:允许留空
- select-in-range:范围内选择
- preset-ranges:预设范围
- extra-footer:额外底部
- size:三档尺寸
- cell-render:自定义单元格渲染
- components(5.14.0):自定义面板
- external-panel:外部独立使用面板
- buddhist-era(5.14.0):佛历纪元
- status:校验状态
- variant(5.13.0):四档变体
- style-class(6.0.0):语义化类名样式
- placement:弹层方位
- suffix:前缀与后缀
(另有 marked 为 debug 的 multiple-debug、filled-debug、mode(受控面板)、start-end(自定义 RangePicker)、render-panel(内部面板)、component-token、suffixIcon-debug 等调试示例,用于开发期验证,一般不建议直接照搬到业务中。)
FAQ:高频问题与官方解答
设置 mode 后无法再选择年或月了?
若你在 mode 固定面板层级后发现无法再点选年份/月份进行上级切换,请查阅仓库 docs/react 目录下 FAQ 中关于“When set mode to DatePicker/RangePicker, cannot select year or month anymore”的说明。
为什么选择年份后直接跳到日期面板而不是月份面板?
选完年份后系统直接切换到日期面板、而非月份面板,是一种有意的交互设计:它希望用户一次点击即可完成年份修改,无需再进入月份选择界面,从而减少操作负担,也避免用户额外记忆当前月份。
如何配合 dayjs 等自定义日期库使用?
DatePicker 的架构基于可注入的日期生成配置(generateConfig),详见仓库 docs/react 目录下 “Use custom date library” 指南中 DatePicker 章节,以及上文“底层架构”部分的分析。
为什么全局配置 dayjs.locale 不生效?
DatePicker 在 v4 起默认把自身 locale 固定为 en。请改用组件 locale 属性或 ConfigProvider 的 locale 属性;若日期相关组件整体语言失效,可再排查仓库 docs/react FAQ 中 “Date-related components locale is not working” 一节。
如何修改一周的起始日?
优先通过正确的语言包设置(参考仓库 docs/react 目录下 i18n 说明与历史 issue #5605),或更新 dayjs 的 locale 配置:
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
import updateLocale from 'dayjs/plugin/updateLocale';
dayjs.extend(updateLocale);
dayjs.updateLocale('zh-cn', {
weekStart: 0, // 以周日为一周开始
});
使用 panelRender 后原始面板为何不再切换?
当你通过 panelRender 改变了节点布局,React 会卸载并重挂该子树,从而重置组件内部状态,导致面板层级无法正常切换。解决方法是保持布局结构稳定(避免让可变化 key/节点结构导致重挂载),详见历史 issue #27263。
如何理解并正确使用“禁用时间与日期”?
disabledDate(按天禁用)、disabledTime(按小时/分/秒禁用)、minDate / maxDate(区间与面板范围限制)三者适用粒度不同。官方文档将其背后的设计思路与完整用法整理在博客专栏 “Why is it so hard to disable the date?”(同主题内容见仓库 docs/blog 下的 picker 相关文章)中;可直接运行的对照示例在 demo/disabled-date.tsx,建议组合 showTime.hideDisabledOptions 隐藏已禁用的时间选项,获得更干净的体验。
小结
从使用层面看,Ant Design DatePicker 以“输入框 + 弹层面板”承载了 date/week/month/quarter/year 与 RangePicker 的全部选择诉求;从实现层面看,它通过 generatePicker 工厂把面板能力与 dayjs 配置解耦,支持多语言、多格式、多选择形态的任意组合。理解 Common API 全表、五种 picker 各自的默认格式与专属属性、locale 双轨配置(AntD 语言包 + dayjs locale)以及语义化 DOM / Design Token 的定制入口,即可在实际项目中从容应对从“一个基础日期输入”到“受控多选 + 范围禁用 + 快捷预设 + 深度换肤”的全场景需求。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00