news 2026/10/16 1:44:11

TDesign UniApp DateTimePicker 时间选择器组件实战指南:引入方式、Mode 类型与 API 全面解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
TDesign UniApp DateTimePicker 时间选择器组件实战指南:引入方式、Mode 类型与 API 全面解析
  • 前端
  • UI组件
  • 小程序
  • 设计系统
  • 移动开发

【免费下载链接】tdesign-miniprogram

Wechat MiniProgram and Uniapp UI components lib for TDesign

项目地址:https://gitcode.com/gh_mirrors/tde/tdesign-miniprogram
点击查看免费下载

DateTimePicker 是 TDesign UniApp 组件库中的时间选择器组件,用于帮助用户选择一个时间点或一个时间段。它基于t-picker与t-picker-item组合实现,内置了年月日、年月、时分秒等多种粒度模式,支持弹出层(Popup)包裹、步数间隔调整、范围限制(start/end)、国际化语言切换以及v-model:value双向绑定。读完本文,你将掌握该组件从引入配置、Mode 模式选择到完整 Props/Events/Slots 使用的全部要点,并能结合源码理解其底层列生成与边界裁剪原理。

一、组件引入方式

easycom 模式(推荐)

推荐使用 easycom 模式引入组件,配置后无需手动import即可直接在模板中使用<t-date-time-picker />。easycom 的详细配置可参考 快速开始,核心是在pages.json中添加:

{ "easycom": { "custom": { "^t-(.*)": "@tdesign/uniapp/$1/$1.vue" } } }

若使用 HBuilderX 的uni_modules方式,则路径应写为"@/uni_modules/tdesign-uniapp/components/$1/$1.vue",具体差异同样参见快速开始文档。

手动引入

如果不使用 easycom,可以在<script>中手动引入组件:

import TDateTimePicker from '@tdesign/uniapp/date-time-picker/date-time-picker.vue';

在示例代码中可以看到,它通常与t-cell组合使用:点击t-cell弹出选择器,再通过@change事件回填结果,例如 year-month-date 示例:

<t-cell title="选择日期" hover :note="dateText || ''" arrow @click="showPicker" /> <t-date-time-picker :visible="dateVisible" auto-close title="选择日期" mode="date" :default-value="date" format="YYYY-MM-DD ddd" @update:visible="(e) => (dateVisible = e)" @change="onConfirm" @pick="onColumnChange" @cancel="hidePicker" />

二、组件类型:Mode 决定了选择粒度

mode是 DateTimePicker 最核心的属性,它直接决定选择器包含哪些滚轮列。根据 mode 取值,组件覆盖了「年月日」「年月」「时分秒/时分」「年月日时分秒」四类典型场景。

年月日选择器(mode="date")

最常见的生日、预约日期选择场景,滚轮包含「年、月、日」三列。结合show-week还能在日期旁显示周几,示例见 year-month-date/index.vue。

年月选择器(mode="month")

滚轮只包含「年、月」两列,适合信用卡有效期、账单月份等场景,示例见 year-month/index.vue:

<t-date-time-picker :visible="monthVisible" title="选择日期" mode="month" :value="month" format="YYYY-MM" :start="start" :end="end" @change="onConfirm" />

时间选择器(时分秒、时分)

时间选择器包含两个示例:时分秒与时分。从 time/index.vue 的写法可以看出,此时 mode 使用数组形式且第一个元素为'null':

<!-- 时分秒 --> <t-date-time-picker :visible="secondVisible" title="选择时间" :mode="['null', 'second']" :value="second" format="HH:mm:ss" @change="onConfirm" /> <!-- 时分 --> <t-date-time-picker :visible="minuteVisible" title="选择时间" :mode="['null', 'minute']" :value="minute" format="HH:mm" @change="onConfirm" />

年月日时分秒选择器(mode="second")

需要精确到秒的完整日期时间选择,示例见 date-all/index.vue,其 mode 写为'second'(或mode="date"搭配数组模式),format 使用'YYYY-MM-DD HH:mm:ss'。

Mode 取值表

| mode 取值 | 含义 | 生成的滚轮列 | | -- | -- | -- | |year| 年 | 年 | |month| 年月 | 年、月 | |date| 年月日(默认值) | 年、月、日 | |hour| 年月日时 | 年、月、日、时 | |minute| 年月日时分 | 年、月、日、时、分 | |second| 年月日时分秒 | 年、月、日、时、分、秒 | | 数组(两个元素) | 第一个值控制年月日,第二个值控制时分秒 | 两组列拼接 |

关于数组模式的底层行为,从 date-time-picker.vue 源码中的getFullModeArray方法可以看到其实现逻辑:当mode为数组且长度为 2 时,第一个元素会通过getFullModeByModeString在DATE_MODES(['year','month','date'])中展开,第二个元素则在TIME_MODES(['hour','minute','second'])中展开,最终拼接成完整的列类型数组fullModes。因此['null', 'second']会展开为['hour','minute','second'],正好得到时分秒三列。

DateTimePickerMode与TimeModeValues的类型定义见 type.ts:

export type DateTimePickerMode = TimeModeValues | Array<TimeModeValues>; export type TimeModeValues = 'year' | 'month' | 'date' | 'hour' | 'minute' | 'second' | 'null';

三、组件用法:调整步数与不使用 Popup

调整步数(steps)

通过steps属性可以控制滚轮列的间隔步长,例如{ minute: 5 }表示分钟列每 5 分钟一个选项。示例见 steps/index.vue:

<t-date-time-picker :visible="visible" title="选择时间" :value="value" format="HH:mm:ss" :mode="['null', 'second']" :steps="{ minute: 5 }" @change="onConfirm" />

从源码看,steps的类型为{ [key in TimeModeValues]?: number },在getOptionByType方法中通过const step = coalesce(steps?.[type], 1)读取对应列的步长,默认值为 1。因此你可以对 year、month、date、hour、minute、second 任意一列单独设置步数。

不使用 Popup(use-popup)

默认情况下组件用弹出层包裹,use-popup默认为true。如果希望选择器直接内嵌在页面中展示(例如固定显示在表单区域),可以设置:use-popup="false",此时无需手动控制visible。示例见 without-popup/index.vue:

<t-date-time-picker :use-popup="false" title="选择日期" mode="date" :value="value" format="YYYY-MM-DD" :start="start" :end="end" @change="onConfirm" @pick="onColumnChange" />

同时该示例也演示了start/end限定可选区间的用法:start传入'2000-01-01 00:00:00'、end传入'2030-09-09 12:12:12',组件会在这两个边界之间生成可选项,超出边界的年、月、日、时、分、秒列会自动裁减。

四、DateTimePicker Props 详解

完整 Props 定义可参考 props.ts 与 type.ts,下表为全部可配置属性:

| 名称 | 类型 | 默认值 | 描述 | 必传 | | -- | -- | -- | -- | -- | | custom-style | Object | - | 自定义样式 | N | | auto-close | Boolean | false | 自动关闭;在确认、取消、点击遮罩层自动关闭,不需要手动设置 visible | N | | cancel-btn | String | 取消 | 取消按钮文字 | N | | confirm-btn | String | - | 确定按钮文字 | N | | custom-locale | String | zh | 组件国际化语言,支持:简体中文(zh)、繁体(tc)、英文(en)、日语(ja)、韩语(ko)、俄语(ru) 六种语言 | N | | end | String / Number | - | 选择器的最大可选时间,默认为当前时间 +10 年 | N | | filter | Function | - | 列选项过滤函数,支持自定义列内容(type 值可为 year、month、date、hour、minute、second)。TS 类型:(type: TimeModeValues, columns: DateTimePickerColumn) => DateTimePickerColumn,其中DateTimePickerColumn = DateTimePickerColumnItem[],DateTimePickerColumnItem = { label: string, value: string }| N | | format | String | 'YYYY-MM-DD HH:mm:ss' | 用于格式化 pick、change、confirm 事件返回的值(基于 day.js 的 format 语法) | N | | formatter | Function | - | 格式化标签。TS 类型:(option: DateTimePickerColumnItem, columnIndex: number) => DateTimePickerColumnItem| N | | header | Boolean | true | 头部内容。true 显示空白头部,false 不显示任何内容 | N | | mode | String / Array | 'date' | 选择模式,取值见上文 Mode 表 | N | | popup-props | Object | {} | 透传 Popup 组件全部属性,TS 类型为PopupProps,参见 Popup API 文档 | N | | show-week | Boolean | false | 是否在日期旁边显示周几(如周一、周二、周日等) | N | | start | String / Number | - | 选择器的最小可选时间,默认为当前时间 -10 年 | N | | steps | Object | {} | 时间间隔步数,示例:{ minute: 5 }。TS 类型:{ [key in TimeModeValues]?: number }| N | | title | String | - | 标题 | N | | use-popup | Boolean | true | 是否使用弹出层包裹 | N | | value | String / Number | - | 选中值,支持语法糖v-model:value。TS 类型:DateValue = string \| number| N | | default-value | String / Number | - | 选中值(非受控属性),TS 类型同value| N | | visible | Boolean | false | 是否显示 | N |

关键属性的源码级原理

value 与 default-value:源码中通过coalesce(this.value, this.defaultValue)合并受控与非受控值,value变化时会通过watch同步到内部dataValue。从controlledProps配置看,value是受控属性,与change事件绑定,因此支持v-model:value双向绑定。

format 格式化:组件内部使用 day.js 完成日期解析与格式化。在onConfirm、onColumnChange中均通过format ? date.format(format) : date.valueOf()计算事件返回值——即设置了format时返回格式化字符串,未设置时返回时间戳数值。因此示例中既有传入new Date('2021-12-23').getTime()时间戳的写法,也有传入'2021-09'、'10:00:00'字符串的写法。

start / end 边界:getMinDate与getMaxDate分别使用dayjs().subtract(10, 'year')与dayjs().add(10, 'year')作为默认边界,即默认允许选择「当前时间 ±10 年」。同时clipDate方法会把当前日期钳制在最小、最大边界之间,确保数据不越界;getOptionEdge则会根据当前选中值与边界值逐列比较,动态裁剪每一列的可用选项,例如当年份已达end边界时,月份、日期列只展示到边界对应的值。

filter 与 formatter 的区别:filter在列选项生成后对整个选项数组进行过滤/排序(如示例中把年份列倒序排列);formatter则逐项修改单个选项的 label 展示(如 year-month-date/index.vue 中把中文月份转换为英文月份名、把"日"后缀转为st/nd/rd)。二者在getColumnOptions与t-picker-item的:format中分别被应用。

custom-locale 国际化:语言包映射见 locale/dayjs.js,组件不仅切换按钮文字(确定/取消)与列后缀(年/月/日/时/分/秒),还会同步切换 dayjs 自身的 locale(zh-cn、zh-tw、en、ja、ko、ru),保证月份缩写、周几名称等随语言正确变化,并做了zh、tc、kr等别名容错。

五、DateTimePicker Events

| 名称 | 参数 | 描述 | | -- | -- | -- | | cancel | - | 取消按钮点击时触发 | | change |(context: { value: DateValue })| 确认按钮点击时触发(受控 value 同步事件) | | close |(context: { trigger: DateTimePickerTriggerSource })| 关闭时触发,DateTimePickerTriggerSource = 'overlay' \| 'cancel-btn' \| 'confirm-btn'| | confirm |(context: { value: DateValue })| 确认按钮点击时触发 | | pick |(context: { value: DateValue })| 选中值发生变化时触发 |

从 date-time-picker.vue 源码可见事件触发链路:onConfirm依次调用_trigger('change', { value })与$emit('confirm', { value }),因此change事件兼顾了v-model:value的受控同步与业务回调用途;onClose会额外$emit('update:visible', false),配合模板中的@update:visible即可实现visible的双向同步(示例中普遍采用这种写法)。另外组件内部对 mode 的监听做了JSON.stringify相等性判断,避免 pick 事件重复触发。

六、Slots 与 External Classes

Slots

| 名称 | 描述 | | -- | -- | | footer | 底部内容 | | header | 自定义header显示内容 |

两个插槽在模板中分别透传给了内部t-picker的#footer与#header,可用于自定义确认按钮区域或头部提示内容。

External Classes

| 类名 | 描述 | | -- | -- | | t-class | 根节点样式类 | | t-class-cancel | 取消样式类 | | t-class-confirm | 确认样式类 | | t-class-title | 标题样式类 |

外部样式类定义于 date-time-picker.vue 的externalClasses配置中,可在使用方通过t-class、t-class-cancel等属性覆盖内部样式。

七、CSS Variables 样式定制

组件提供 CSS 变量用于自定义样式(见 date-time-picker.less):

| 名称 | 默认值 | 描述 | | -- | -- | -- | | --td-data-time-picker-year-width | 128rpx | 年份列宽度 |

该变量主要作用于「年月日时分秒」这类列数较多(5 列及以上)的场景:源码模板中当columns.length >= 5 && index == 0时,会为第一列(年份列)追加--roomly样式类,通过该 CSS 变量固定年份列宽度,避免在 5~6 列拥挤布局下年份列被压缩变形。可按需覆盖调整,例如:

:root { --td-data-time-picker-year-width: 160rpx; }

八、实战组合建议

综合以上 API,一个典型的「受控 + 自动关闭 + 限定范围 + 自定义文案」的完整用法可组合如下:

<t-date-time-picker v-model:value="birthday" :visible="visible" auto-close title="选择出生日期" mode="date" format="YYYY-MM-DD" :start="'1900-01-01'" :end="today" :steps="{ date: 1 }" cancel-btn="返回" confirm-btn="确定" @confirm="onConfirm" @close="onClose" />

需要进一步查看组件内部实现细节(列生成、边界裁剪、国际化映射)时,可直接阅读 date-time-picker.vue、type.ts 以及_example目录下的六组官方示例。

  • 前端
  • UI组件
  • 小程序
  • 设计系统
  • 移动开发

【免费下载链接】tdesign-miniprogram

Wechat MiniProgram and Uniapp UI components lib for TDesign

项目地址:https://gitcode.com/gh_mirrors/tde/tdesign-miniprogram
点击查看免费下载

相关推荐

上一篇:如何快速提取微信聊天记录:打造个人AI助手的完整指南
下一篇:Markoff未来路线图:即将推出的功能与改进计划

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 1:43:41

软考 系统架构设计师历年真题集萃(116)

接前一篇文章:软考 系统架构设计师系列知识点之杂项集萃(115) 第213题 ANSI/IEEE 1471-2000是对软件密集型系统的架构进行描述的标准。在该标准中,( )这一概念主要用于描述架构模型。在此基础上,通常采用( )描述某个利益相关人(Stakeholder)所关注架构模型的某一方…

作者头像 李华
网站建设 2026/10/16 1:42:33

Javaweb面试题库项目Q_ITOffer:架构解析与二次开发实战

简介&#xff1a;Q_ITOffer.rar 是一套面向 Java Web 初学者与进阶开发者的招聘网站后台管理系统实战源码&#xff0c;基于 MyBatis 持久层框架&#xff0c;结合 Servlet、JSP、jQuery、JavaScript、HTML、CSS 与 MySQL 数据库构建&#xff0c;可用于课程设计、毕业设计参考或后…

作者头像 李华
网站建设 2026/10/16 1:41:57

阿波罗11号AGC制导计算机:磁芯存储与解释器架构的工程复现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华