Refine Ant Design DateField 组件实战:基于 Day.js 的日期字段渲染、国际化与源码解析 Refine Ant Design DateField 组件实战基于 Day.js 的日期字段渲染、国际化与源码解析【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refineDateField是 Refine v5 中 Ant Design UI 集成包refinedev/antd提供的一个展示型字段组件专门用于在列表、详情等页面中以可读的文本形式渲染日期。它的核心是借助Day.js完成格式化并天然继承 Ant DesignTypography.Text的全部能力因此在后台管理系统、管理面板和 B2B 应用中你可以用一行代码把数据库里的时间戳变成符合本地习惯的日期文本。读完本文你将掌握DateField的完整用法、format与locales参数的行为边界、底层实现原理以及如何通过 Refine CLI 将其 swizzle 出来做深度定制。认识 DateField一个基于 Day.js 的轻量日期展示组件在 Refine 中字段组件Field Components是一类专门用于展示型渲染的 UI 组件与TextField、NumberField、BooleanField等并列统一从refinedev/antd导出。DateField的作用只有一个接收一个日期值按指定的格式字符串渲染为文本。它本身不负责数据获取也不管理表单状态只负责把值变成好看的文本。从官方文档的定义看该组件用于显示日期并使用Day.js来显示日期格式。Day.js 是一个轻量的 JavaScript 日期库其format()方法通过一组语义化的 token如YYYY、MM、DD、HH:mm来生成任意格式的日期字符串而DateField正是基于这套 token 体系工作的。在 Refine 的组件体系里DateField定义于 packages/antd/src/components/fields/date/index.tsx并与其他字段组件一起在 packages/antd/src/components/fields/index.ts 中统一导出export { DateField } from ./date; // 其余还有 TextField、TagField、EmailField、ImageField、BooleanField、 // FileField、UrlField、NumberField、MarkdownField 等快速上手在帖子列表中渲染日期字段DateField最常见的应用场景是配合useTable与 Ant Design 的Table使用在表格列中展示记录的创建时间。以下示例完整来自官方文档在帖子posts列表中渲染createdAt字段setInitialRoutes([/posts]); // visible-block-start import { List, useTable, DateField } from refinedev/antd; import { Table } from antd; const PostList: React.FC () { const { tableProps } useTableIPost(); return ( List Table {...tableProps} rowKeyid Table.Column dataIndexid titleID / Table.Column dataIndextitle titleTitle / Table.Column dataIndexcreatedAt titleCreated At // highlight-next-line render{(value) DateField value{value} /} / /Table /List ); }; interface IPost { id: number; title: string; createdAt: string; } // visible-block-end render( ReactRouter.BrowserRouter RefineAntdDemo resources{[ { name: posts, list: /posts, }, ]} ReactRouter.Routes ReactRouter.Route path/posts element{ div style{{ padding: 16 }} PostList / /div } / /ReactRouter.Routes /RefineAntdDemo /ReactRouter.BrowserRouter, );要点拆解useTableIPost()返回的tableProps会接管表格的dataSource、分页、loading 等状态在Table.Column中我们只关心createdAt这一列通过render回调把原始值交给DateField value{value} /不传format时DateField会使用默认格式L即 Day.js 的本地化格式 token输出形如05/20/2021的本地日期文本组件内部最终渲染为 Ant Design 的Typography.Text所以它天然拥有 Typography 的文本样式与省略、复制等扩展能力。属性 API 详解DateField的属性定义在 packages/antd/src/components/fields/types.ts 中export type DateFieldProps RefineFieldDatePropsConfigType, TextProps;其中ConfigType是 Day.js 的输入类型string | number | Date | DayjsTextProps是 Ant DesignTypography.Text的 props。基础属性来自refinedev/ui-types的RefineFieldDateProps定义于 packages/ui-types/src/types/field.tsx属性类型默认值说明valueConfigTypestring/number/Date/Dayjs—必填。要展示的日期值。formatstringLDay.jsformat()的 token 字符串控制日期文本的呈现格式。localesstring当前全局 locale即dayjs.locale()的返回值默认 English渲染该字段时使用的 Day.js locale 标识如tr、de。value可接受多种日期输入value的类型是 Day.js 的ConfigType意味着你可以直接传入ISO 字符串2021-05-20、2021-05-20T10:30:00Z时间戳number1621468800000Date对象new Date(2021-05-20)已经构造好的Dayjs实例组件内部统一通过dayjs(value)进行解析无需你预先做类型转换。format用 Day.js token 定义输出样式format直接透传给 Day.js 的.format()方法默认值是L。L与l属于 Day.js 的localizedFormat插件提供的本地化 token它们会根据当前 locale 自动替换为对应地区的日期样式例如美式英语下L等价于MM/DD/YYYY。常用的自定义 token 包括Token含义示例输出YYYY四位数年份2021YY两位数年份21MM补零月份05M不补零月份5DD补零日期20D不补零日期20HH:mm24 小时制时分14:30hh:mm A12 小时制时分与上下午02:30 PMLL/ll本地化长/短日期May 20, 2021/May 20, 2021依 locale 而定L/l本地化日期05/20/2021/5/20/2021例如要渲染为日/月/年顺序的欧洲风格日期可以写DateField value{post.createdAt} formatDD/MM/YYYY /locales按需加载的多语言日期Day.js 默认只内置英语 locale其他语言需要按需加载。locales属性正是为单个字段指定语言而设计的——你可以在应用中加载多个 locale然后让不同的字段使用不同语言渲染。import dayjs/locale/tr; DateField value{post.createdAt} formatll localestr /如果不传locales组件会回退到dayjs.locale()返回的全局 locale。继承 Ant Design Typography.Text 的属性DateField的 props 还合并了 Ant DesignTypography.Text的全部属性。文档中明确说明该字段还接受 Ant Design Text 组件的所有 props。因此你可以直接使用copyable、ellipsis、strong、type等 Text 特性DateField value{post.createdAt} strong typesecondary /这使得日期文本在保持格式化能力的同时能够无缝融入 Ant Design 的排版体系。源码实现解析一行组件背后的完整逻辑DateField的实现非常精简完整源码位于 packages/antd/src/components/fields/date/index.tsximport React from react; import dayjs from dayjs; import { Typography } from antd; import LocalizedFormat from dayjs/plugin/localizedFormat; import type { DateFieldProps } from ../types; export const DateField: React.FCDateFieldProps ({ value, locales, format: dateFormat L, ...rest }) { dayjs.extend(LocalizedFormat); const defaultLocale dayjs.locale(); return ( Typography.Text {...rest} {value ? dayjs(value) .locale(locales || defaultLocale) .format(dateFormat) : } /Typography.Text ); };从源码可以提炼出几个关键实现事实默认格式来自解构默认值format: dateFormat L即组件级默认格式是L本地化日期。这与文档 API 表格中标注的format-defaultL完全一致。localizedFormat 插件按需挂载组件内部调用dayjs.extend(LocalizedFormat)确保L、l、LL等本地化 token 可用。locale 的解析顺序locales属性优先其次回退到dayjs.locale()的全局 locale。也就是说即使你不在应用里手动设置全局 locale组件也能跟随 Day.js 的当前全局语言环境工作。空值处理当value为null、undefined或其他 falsy 值时组件渲染为空字符串而不是渲染Invalid Date或抛错。这一行为让后端字段缺失的记录在表格中显示为空白而不是一串错误文本。渲染载体最终输出被包裹在Typography.Text中这也是它能继承 Text 全部属性的原因。边界情况与测试验证空值、非法日期与本地化格式DateField的跨包共享测试套件位于 packages/ui-tests/src/tests/fields/date.tsx由 packages/antd/src/components/fields/date/index.spec.tsx 直接绑定运行import { fieldDateTests } from refinedev/ui-tests; import { DateField } from ./; describe(DateField, () { fieldDateTests.bind(this)(DateField); });这些测试用例精确刻画了组件的行为边界你可以把它们当作可运行的规格说明测试场景输入期望输出默认格式value{new Date(2021-05-20)}05/20/2021L格式美式月/日/年自定义格式formatDD/MM/YYYY20/05/2021本地化格式 localesformatl localestr20.5.2021土耳其语 locale无 locales 回退formatl全局 locale 为 en5/20/2021空值 nullvalue{null}空字符串空值 undefinedvalue{undefined}空字符串非法日期value{new Date(test)}Invalid Date其中本地化格式 locales这一组测试特别值得注意同样的value与formatl在localestr下渲染为20.5.2021在默认英语 locale 下渲染为5/20/2021——这正是 Day.js 本地化格式 token 的价值所在同一个 token 在不同语言环境下呈现不同的地区习惯。同时也要留意如果传入的是一个无法解析的非法日期如new Date(test)组件不会拦截而是会把 Day.js 的Invalid Date文本直接渲染出来。因此如果你对接的数据源可靠性存疑可以在传入前自行校验日期合法性。使用 Refine CLI swizzle 深度定制如果你觉得默认行为不够用例如希望把非法日期渲染为—、或者希望默认输出YYYY-MM-DD HH:mm风格官方推荐的方式是通过Refine CLI的 swizzle 能力把组件源码复制到你的项目中再修改。文档中的 Good to know 提示明确指出你可以使用 Refine CLI 对该组件执行 swizzle 操作以进行自定义。swizzle 后你会得到一份组件源码副本可以在此基础上自由调整渲染逻辑比如修改空值分支、改变默认格式、增加 Tooltip 等而不影响 Refine 包本身。关于 swizzle 命令的详细用法可参考仓库中的 Refine CLI 文档。总结DateField是refinedev/antd提供的日期展示组件基于 Day.js 的format()完成格式化默认输出本地化格式L核心属性仅三个value任意可被 Day.js 解析的日期输入、formattoken 字符串、locales按需加载的语言标识并完整继承 Ant DesignTypography.Text的 props从源码实现index.tsx看它内部通过dayjs.extend(LocalizedFormat)启用本地化 tokenlocale 解析顺序为字段级locales优先、全局dayjs.locale()兜底null/undefined渲染为空字符串共享测试套件packages/ui-tests/src/tests/fields/date.tsx覆盖了默认格式、自定义格式、多语言、空值与非法日期等全部关键行为可作为使用时的行为参考当默认能力无法满足需求时可通过 Refine CLI 对组件进行 swizzle在项目内获得可编辑的源码副本。在构建国际化后台时把DateField与全局 locale 管理如 i18n provider配合使用即可用最少的代码让所有日期字段自动适配不同地区用户的阅读习惯。【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考