cube-ui TimePicker 时间选择器完全指南:从 API 配置到源码级原理
发布时间:2026/9/25 5:48:26来源:尧图网络
前端UI组件移动开发【免费下载链接】cube-ui:large_orange_diamond: A fantastic mobile ui lib implement by Vue项目地址https://gitcode.com/gh_mirrors/cu/cube-ui点击查看免费下载TimePicker是 cube-ui 中基于 Picker/CascadePicker 封装的三列联动时间选择组件日期 小时 分钟面向移动端场景提供“日期列 时间列”的级联滚动选择能力并支持现在快捷项、分钟步长、最小/最大可选时间边界以及手动置位等能力。阅读本文后你将掌握$createTimePicker的全部配置项、事件与实例方法并能结合源码理解其列数据生成与取整规则背后的实现原理。TimePicker组件提供了常用的日期选择功能。由于该组件基于 create-api 实现因此在正式使用之前请确保先了解 create-api 的用法——正是通过$createTimePicker这一命令式 API我们才能像调用函数一样快捷地创建并弹出时间选择器。基本用法命令式创建与事件回调TimePicker通过$createTimePicker方法创建调用后返回实例再调用实例的show()方法即可弹出。以下是最基本的用法cube-button clickshowTimePickerTimePicker/cube-buttonexport default { methods: { showTimePicker () { this.$createTimePicker({ showNow: true, minuteStep: 5, delay: 15, onSelect: (selectedTime, selectedText, formatedTime) { this.$createDialog({ type: warn, title: selected time: ${selectedTime}, content: selected text: ${selectedText}brformat time: ${formatedTime}, icon: cubeic-alert }).show() }, onCancel: () { this.$createToast({ type: correct, txt: Picker canceled, time: 1000 }).show() } }).show() } } }showNow用于控制是否显示现在时间选项默认trueminuteStep用于控制分钟的步长例如设为 5 时分钟列只出现 0、5、10、15…… delay表示当前时间向后推迟的分钟数它决定了最小可选时间默认 15 分钟即默认最早可选 15 分钟之后的时间。从源码看showNow、minuteStep、delay等配置会被传入 time-picker.vue 中定义的同名 props组件内部再把这些配置转化为级联列数据cascadeData交给底层的cube-cascade-picker渲染。这也是 TimePicker 模板部分仅有一个cube-cascade-picker元素的原因cube-cascade-picker refpicker v-modelisVisible :datacascadeData :selected-indexselectedIndex :title_title :subtitlesubtitle :cancel-txt_cancelTxt :confirm-txt_confirmTxt :swipe-timeswipeTime :z-indexzIndex :mask-closablemaskClosable select_pickerSelect cancel_pickerCancel change_pickerChange /cube-cascade-picker日期选项配置day 的 len / filter / formatday字段用于配置第一列日期列的展示方式cube-button clickshowTimePickerTimePicker - day options/cube-buttonexport default { methods: { showTimePicker () { this.$createTimePicker({ showNow: true, minuteStep: 10, delay: 10, day: { len: 5, filter: [今天, 明天], format: M月d日 }, onSelect: (selectedTime, selectedText, formatedTime) { this.$createDialog({ type: warn, title: selected time: ${selectedTime}, content: selected text: ${selectedText}brformat time: ${formatedTime}, icon: cubeic-alert }).show() }, onCancel: () { this.$createToast({ type: correct, txt: Picker canceled, time: 1000 }).show() } }).show() } } }len设置日期列需要展示的日期长度从当前时间算起往后推的天数默认 3注仅当未设置max时有效filter设置日期列展示的文案将日期映射为数组中的文案内容例如[今天, 明天]format格式化日期显示的方式例如M月d日。当len的数量大于filter数组长度时超出部分会按format的格式显示文案。结合 time-picker.vue 的days计算属性可以看到具体实现组件从minTime开始逐天生成时间戳文案优先取filter[dayDiff i]即 filter 数组中对应天数的文案取不到时才回退到formatDate(new Date(timestamp), this._day.format)days() { const days [] const dayDiff getDayDiff(this.minTime, this.now) const len this.max ? getDayDiff(this.maxTime, this.minTime) 1 : this._day.len for (let i 0; i len; i) { const timestamp this.minTime i * DAY_TIMESTAMP days.push({ value: timestamp, text: (this._day.filter this._day.filter[dayDiff i]) || formatDate(new Date(timestamp), this._day.format) }) } return days }注意day的默认值定义在 time-picker.vue 中只有{ len: 3 }而filter默认[今日]与format默认M月D日来自 locale 多语言配置参见 _day 计算属性 与 zh-CN locale 文件。配置 select 事件的格式化时间format1.10.0通过format属性可以配置select事件第三个参数formatedTime的格式默认值为YYYY/M/D hh:mmcube-button clickshowFormatPickerConfig format/cube-buttonexport default { methods: { showFormatPicker() { if (!this.formatPicker) { this.formatPicker this.$createTimePicker({ format: hh:mm, onSelect: this.selectHandler, onCancel: this.cancelHandler }) } this.formatPicker.show() }, selectHandler(selectedTime, selectedText, formatedTime) { this.$createDialog({ type: warn, title: selected time: ${selectedTime}, content: selected text: ${selectedText}brformat time: ${formatedTime}, icon: cubeic-alert }).show() }, cancelHandler() { this.$createToast({ type: correct, txt: Picker canceled, time: 1000 }).show() } } }format支持的时间占位符由 src/common/lang/date.js 中的formatDate函数解析包括Y年、M月、D日、h小时、m分钟、s秒、q季度、S毫秒。占位符重复出现时如hh会自动补零例如 9 点 5 分按hh:mm格式化得到09:05。这一格式化能力同时被组件的 select 事件与测试用例复用参见 time-picker.spec.js 中 format 相关断言。分钟步长 minuteStep数字与对象两种形态通过minuteStep属性可配置分钟数的步长默认为 10 分钟。此时可选的分钟为 10、20、30、40、50。在 v1.10.5 中minuteStep还支持传入一个对象通过子属性rule配置取整规则ceil向上取整、floor向下取整、round四舍五入子属性step表示步长cube-button clickshowMinuteStepPickerConfig minute step/cube-buttonexport default { methods: { showFormatPicker() { if (!this.minuteStepPicker) { this.minuteStepPicker this.$createTimePicker({ minuteStep: { rule: ceil, step: 15 }, onSelect: this.selectHandler, onCancel: this.cancelHandler }) } this.minuteStepPicker.show() }, selectHandler(selectedTime, selectedText, formatedTime) { this.$createDialog({ type: warn, title: selected time: ${selectedTime}, content: selected text: ${selectedText}brformat time: ${formatedTime}, icon: cubeic-alert }).show() }, cancelHandler() { this.$createToast({ type: correct, txt: Picker canceled, time: 1000 }).show() } } }minuteStep对象形态的rule仅用于最小可选时间的取整对于最大时间组件固定使用floor规则。相关实现位于 minuteStepRule / minuteStepNumber 计算属性minuteStepRule() { const minuteStep this.minuteStep return (typeof minuteStep object Math[INT_RULE[minuteStep.rule]]) || Math[INT_RULE.floor] }, minuteStepNumber() { const minuteStep this.minuteStep return typeof minuteStep number ? minuteStep : (minuteStep.step || DEFAULT_STEP) }其中INT_RULE { floor: floor, ceil: ceil, round: round }DEFAULT_STEP 10定义在组件文件顶部time-picker.vue 第 46-52 行。测试用例 testMinuteStep 覆盖了数字、{rule: ceil}、{step: 15}、{rule: floor, step: 5}、{rule: round, step: 10}等多种配置验证列数据首项与Mathrule * step一致。最小可选时间 min1.12.6通过min属性可设置最小可选时间。它既可以接受Date类型的日期时间也可以接受Number类型的时间戳cube-button clickshowMinPickerConfig min/cube-buttonexport default { methods: { showMinPicker() { if (!this.minPicker) { this.minPicker this.$createTimePicker({ min: new Date() - (2 * 60 20) * 60 * 1000, onSelect: this.selectHandler, onCancel: this.cancelHandler }) } this.minPicker.show() }, selectHandler(selectedTime, selectedText, formatedTime) { this.$createDialog({ type: warn, title: selected time: ${selectedTime}, content: selected text: ${selectedText}brformat time: ${formatedTime}, icon: cubeic-alert }).show() }, cancelHandler() { this.$createToast({ type: correct, txt: Picker canceled, time: 1000 }).show() } } }上例中min被设置为当前时间往前 2 小时 20 分钟的时间戳即允许用户选择过去 2 小时 20 分钟以内的任意时间点。从源码看minTime 计算属性 的优先级是this.min || this.now this.delay * MINUTE_TIMESTAMP——即设置min后delay将不再生效文档 Props 表中delay也注明了仅当未设置min时有效。同时minTime会按minuteStepRule对分钟取整例如默认floor规则下 10 点 37 分会被对齐到 10 点 30 分minTime() { let minTimeStamp this.min || this.now this.delay * MINUTE_TIMESTAMP // Handle the minTime selectable change caused by minute step. const minute new Date(minTimeStamp).getMinutes() const intMinute Math.min(this.minuteStepRule(minute / this.minuteStepNumber) * this.minuteStepNumber, 60) minTimeStamp (intMinute - minute) * MINUTE_TIMESTAMP return new Date(minTimeStamp) }对应的边界测试见 testMin 用例其验证了min为 null 以及正负多种时间偏移时日期列长度始终等于getDayDiff(vm.maxTime, vm.minTime) 1。最大可选时间 max1.12.6通过max属性可设置最大可选时间同样支持Date类型或Number类型时间戳cube-button clickshowMaxPickerConfig max/cube-buttonexport default { methods: { showMaxPicker() { if (!this.maxPicker) { this.maxPicker this.$createTimePicker({ delay: 0, max: new Date() ((2 * 24 2) * 60 20) * 60 * 1000, onSelect: this.selectHandler, onCancel: this.cancelHandler }) } this.maxPicker.show() }, selectHandler(selectedTime, selectedText, formatedTime) { this.$createDialog({ type: warn, title: selected time: ${selectedTime}, content: selected text: ${selectedText}brformat time: ${formatedTime}, icon: cubeic-alert }).show() }, cancelHandler() { this.$createToast({ type: correct, txt: Picker canceled, time: 1000 }).show() } } }上例中max为当前时间往后 2 天 2 小时 20 分钟同时delay: 0使最小可选时间即为当前时刻。max的设置同样会让day.len失效——days 计算属性 中const len this.max ? getDayDiff(this.maxTime, this.minTime) 1 : this._day.len即日期列长度改由min与max的跨度决定。maxTime 计算属性 的默认值逻辑是minTime 当天之后_day.len天的零点再减 1 毫秒并且对最大时间固定使用floor取整分钟maxTime() { let maxTimeStamp this.max || (getZeroStamp(new Date(this.minTime this._day.len * DAY_TIMESTAMP)) - 1) const minute new Date(maxTimeStamp).getMinutes() const intMinute Math.floor(minute / this.minuteStepNumber) * this.minuteStepNumber maxTimeStamp - (minute - intMinute) * MINUTE_TIMESTAMP return new Date(maxTimeStamp) }一个值得注意的边界当maxTime比minTime小超过一个分钟步长源码判定阈值为-60000即 1 分钟时cascadeData会返回空数组并输出警告 The max is smaller than the min optional time.对应逻辑见 cascadeData 计算属性。相关测试见 testMax 用例。手动设置时间setTime 实例方法timePicker实例向外暴露setTime方法用于手动设置组件显示的时间参数为时间戳。当时间戳小于当前时间戳时实例会默认显示当前时间cube-button clickshowTimePickerTimePicker - setTime(next hour)/cube-buttonexport default { methods: { const time new Date().valueOf() 1 * 60 * 60 * 1000 showTimePicker () { const timePicker this.$createTimePicker({ showNow: true, minuteStep: 10, delay: 15, day: { len: 5, filter: [今天, 明天, 后天], format: M月D日 }, onSelect: (selectedTime, selectedText, formatedTime) { this.$createDialog({ type: warn, title: selected time: ${selectedTime}, content: selected text: ${selectedText}brformat time: ${formatedTime}, icon: cubeic-alert }).show() }, onCancel: () { this.$createToast({ type: correct, txt: Picker canceled, time: 1000 }).show() } }) timePicker.setTime(time) timePicker.show() } } }setTime的源码实现见 time-picker.vue 第 262-266 行它把时间戳存入内部value若组件当前已可见则立即更新selectedIndex。更完整的索引换算逻辑在 _updateSelectedIndex按天数索引 小时索引 分钟索引换算且当目标时间超出可选范围时会警告 Use setTime to set a time exceeded to the option range do not actually work.。注意当传入时间早于minTime时组件会回退到第一列第一项[0, 0, 0]测试用例还验证了通过setTime将选中时间切到次日时滚轮位移与文案的正确性time-picker.spec.js 第 50-64 行。Props 配置总览| 参数 | 说明 | 类型 | 默认值 | | - | - | - | - | | day | 日期配置 | Object | { len: 3, filter: [今日], format: M月D日 } | | showNow | 是否显示现在以及现在选项的文案1.9.0 支持 Object | Boolean, Object1.9.0 | true | | minuteStep | 分钟数的步长。为 Object 时可配置取整规则详见下方minuteStep子配置项1.10.5 | Number, Object1.10.5 | 10 | | delay | 将当前时间向后推算的分钟数决定最小可选时间注仅当未设置min时有效 | Number | 15 | | min1.12.6 | 最小可选时间 | Date, Number | null | | max1.12.6 | 最大可选时间 | Date, Number | null | | title | 标题 | String | 选择时间 | | subtitle1.8.1 | 副标题 | String | | | cancelTxt1.8.1 | 取消按钮文案 | String | 取消 | | confirmTxt1.8.1 | 确定按钮文案 | String | 确定 | | swipeTime | 快速滑动选择器滚轮时惯性滚动动画的时长单位ms | Number | 2500 | | visible1.8.1 | 显示状态是否可见v-model绑定值 | Boolean | false | | maskClosable1.9.6 | 点击蒙层是否隐藏 | Boolean | true | | format1.10.0 | select 事件参数 formatedTime 的格式 | String | YYYY/M/D hh:mm | | zIndex1.9.6 | 样式 z-index 的值 | Number | 100 |其中title、subtitle、cancelTxt、confirmTxt、swipeTime、maskClosable的定义可追溯至 picker mixincancelTxt/confirmTxt为空时回退到 locale 文案_cancelTxt、_confirmTxttitle为空时则回退到selectTime中文为选择时间参见 time-picker.vue 第 105-108 行。day 子配置项| 参数 | 说明 | 类型 | 默认值 | | - | - | - | - | | len | 日期列从当前时间算起往后推 len 天注仅当未设置max时有效 | Number | 3 | | filter | 日期列将时间映射为 filter 中的文案内容 | Array | [今日] | | format | 时间格式化 | String | M月D日 |showNow 子配置项1.9.0当showNow传入对象时可配置现在选项的文案| 参数 | 说明 | 类型 | 默认值 | | - | - | - | - | | text | 现在选项的文案 | String | 现在 |实现上nowText 计算属性 优先取this.showNow.text否则回退到 locale 默认值现在选项会以{ value: now, text: this.nowText }的形式被unshift到当日小时列的首位cascadeData 中 showNow 处理逻辑并且仅当今天在可选范围内dayDiff 0时才会插入。测试用例分别覆盖了showNow: false、showNow: { text: now text }两种形态time-picker.spec.js 第 69-118 行。minuteStep 子配置项1.10.5| 参数 | 说明 | 类型 | 可选值 | 默认值 | | - | - | - | - | - | | rule | 取整的规则仅用于设置最小可选时间的取整规则对于最大时间固定为 floor | String | floor / ceil / round | floor | | step | 分钟数的步长 | Number | - | 10 |事件| 事件名 | 说明 | 参数1 | 参数2 | 参数3 | | - | - | - | - | - | | select | 点击确认按钮触发此事件 | selectedTime当前选中的 timestamp | selectText当前选中的时间文案 | formatedTime格式化日期1.10.0 | | change | 滚轴滚动后触发此事件 | index当前滚动列次序Number 类型 | selectedIndex当前列选中项的索引Number 类型 | - | | cancel | 点击取消按钮触发此事件 | - | - | - |select事件的触发逻辑见 _pickerSelect当选中的是第一列的现在selectedVal[1] NOW.value时timestamp取new Date()的当前时刻否则由日期零刻时间戳 小时 分钟合成timestamptext形如今日 10:30再经formatDate(new Date(timestamp), this.format)生成formatedTime并随事件抛出。change、cancel则分别由_pickerChange、_pickerCancel透传底层 cascade-picker 的事件time-picker.vue 第 308-328 行。三个事件名[select, cancel, change]同时被注册进 create-api见 src/modules/time-picker/api.js完整的类型定义含onSelect/onCancel/onChange回调签名可查阅 types/components/TimePicker.ts。实例方法| 方法名 | 说明 | 参数 | | - | - | - | | setTime | 手动设置 time-picker 组件显示的时间数据格式为时间戳 | 时间戳 | | show | 显示 | - | | hide | 隐藏 | - |从源码理解组件架构与可选范围推导综合上述内容可以梳理出 TimePicker 的完整工作链路命令式入口Vue.use(TimePicker)时src/modules/time-picker/index.js 会注册cube-picker、cube-time-picker两个组件并分别调用addPicker、addTimePicker注入$createPicker与$createTimePickerAPI$createTimePicker通过createAPI基于vue-create-api见 src/common/helpers/create-api.js生成api.before中会提示 TimePicker 不支持单例模式single传 true 时输出警告对应 api.js 第 6-10 行 与测试用例。列数据生成组件依据min/delay推导minTime依据max/day.len推导maxTime再据此生成日期列days→ 小时列hours→ 分钟列minutes的三级cascadeData。日期列基于 src/common/lang/date.js 的getZeroStamp/getDayDiff计算天数差小时列对首尾两天做裁剪首日从minTime.getHours()起、末日到maxTime.getHours()止分钟列按minuteStepNumber遍历 0~59time-picker.vue 第 161-181 行。级联渲染与交互最终数据交给cube-cascade-picker完成三列滚轮渲染、惯性滑动swipeTime控制惯性时长以及select/change/cancel事件的上抛。国际化标题、按钮文案、now/today文案及formatDate默认值均接入 locale中文默认值见 src/locale/lang/zh-CN.js。可复现的示例完整的可运行示例位于 example/pages/time-picker.vue覆盖基本用法、day 配置、format、minuteStep、min、max、setTime 七种场景单元测试见 test/unit/specs/time-picker.spec.js可作为理解各配置项行为边界的第一手资料。实践建议预约类业务用delay分钟限制最早可选时间或用min/max时间戳或 Date精确限定可选区间两者可组合使用但注意delay在设置min后失效快递/配送时效配合day.len限定未来 N 天并借助day.filter如[今天, 明天]day.format如M月d日定制日期文案注意len在设置max后失效高频操作用format: hh:mm等格式定制select事件回传的formatedTime便于直接渲染或提交业务既有选择回显组件实例创建后可调用setTime(timestamp)定位到指定时间需注意超出可选范围的时间会被忽略并输出警告早于最小可选时间的值会回退到首项自定义文案与样式通过title/subtitle/cancelTxt/confirmTxt覆盖按钮与标题通过zIndex控制层级maskClosable: false可禁止点击蒙层关闭分钟粒度控制按需选择minuteStep数字如 5、15、30或对象形态{ rule: ceil, step: 15 }其中rule只影响最小可选时间的对齐最大时间恒为floor对齐。赞分享前端UI组件移动开发【免费下载链接】cube-ui:large_orange_diamond: A fantastic mobile ui lib implement by Vue项目地址https://gitcode.com/gh_mirrors/cu/cube-ui点击查看免费下载相关推荐PagingKit无Storyboard实现纯代码创建灵活分页菜单的技巧PagingKit无Storyboard实现纯代码创建灵活分页菜单的技巧 PagingKit是一款功能强大的iOS分页菜单库它提供了高度可定制的菜单UI比如何快速接入多品牌监控设备WVP-PROGB28181视频平台完整落地指南如何快速接入多品牌监控设备WVP PROGB28181视频平台完整落地指南 现场里海康、大华、宇视的摄像机各说各话上级平台等着要一份国标28181的级联后端音视频前端Cube-UI 时间选择器 TimePicker 组件深度解析Cube UI 时间选择器 TimePicker 组件深度解析 组件概述 TimePicker 是 Cube UI 提供的一个功能强大的时间选择组件它可以帮助前端UI组件移动开发上一篇如何配置Bruno实现API测试会话持久化告别重复登录的终极指南下一篇标题突出核心价值如IT求职一站式知识库创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网