news 2026/9/12 5:18:42

Element Plus TimePicker 时间选择器完全指南:从基础用法到 API 全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Element Plus TimePicker 时间选择器完全指南:从基础用法到 API 全解析

Element Plus TimePicker 时间选择器完全指南:从基础用法到 API 全解析

【免费下载链接】element-plus🎉 A Vue.js 3 UI Library made by Element team项目地址: https://gitcode.com/GitHub_Trending/el/element-plus

时间选择器(TimePicker)是 Element Plus 组件库中用于时间输入的交互组件,本文基于官方文档 docs/en-US/component/time-picker.md 并结合仓库源码,系统讲解任意时间选择、时间范围限制、区间选择三大核心场景,以及 Attributes、Events、Exposes 的完整 API 说明与底层实现原理。阅读完本文,你将能够熟练配置disabled-hours/minutes/secondsarrow-controlis-range等关键属性,理解formatvalue-format的作用边界,并掌握在 Vue 3 项目中直接落地的完整示例代码。

基础用法:任意时间选择

TimePicker 最基础的形态是选择一个任意时刻,只需引入el-time-picker组件并通过v-model绑定值即可。以下示例来自仓库文档示例 docs/examples/time-picker/basic.vue:

<template> <div class="example-basic"> <el-time-picker v-model="value1" placeholder="Arbitrary time" /> <el-time-picker v-model="value2" arrow-control placeholder="Arbitrary time" /> </div> </template> <script lang="ts" setup> import { ref } from 'vue' const value1 = ref() const value2 = ref() </script>

从源码结构看,ElTimePicker组件(packages/components/time-picker/src/time-picker.tsx)内部由三层协作构成:

  • 外层Picker(common/picker.vue)负责输入框、下拉浮层(popper)与焦点管理等公共逻辑;
  • 面板组件TimePickPanel(time-picker-com/panel-time-pick.vue)负责单值模式的时间面板;
  • 核心滚动列表BasicTimeSpinner(time-picker-com/basic-time-spinner.vue)渲染时、分、秒三个可滚动列。

默认情况下,用户可以在面板中滚动鼠标滚轮来快速切换时分秒。当设置了arrow-control属性后,面板会切换为箭头按钮模式:每个时间列上下各出现一个箭头图标,按住可连续增减数值,更适合触屏或对鼠标滚轮不友好的场景。这一分支逻辑在basic-time-spinner.vue中以v-if="!arrowControl"v-if="arrowControl"两个模板分支实现,箭头模式还复用了@element-plus/directives提供的v-repeat-click指令来支持长按连发。

限制时间范围:禁用不可选的时间点

如果业务要求只能选择某个时间段内的时刻,可以通过disabled-hoursdisabled-minutesdisabled-seconds三个函数属性来精确禁用小时、分钟、秒。以下示例来自 docs/examples/time-picker/basic-range.vue,它把可选项限制在 17:30 到 18:30 之间:

<template> <div class="example-basic"> <el-time-picker v-model="value1" :disabled-hours="disabledHours" :disabled-minutes="disabledMinutes" :disabled-seconds="disabledSeconds" placeholder="Arbitrary time" /> </div> </template> <script lang="ts" setup> import { ref } from 'vue' const value1 = ref(new Date(2016, 9, 10, 18, 30)) const makeRange = (start: number, end: number) => { const result: number[] = [] for (let i = start; i <= end; i++) { result.push(i) } return result } const disabledHours = () => { return makeRange(0, 16).concat(makeRange(19, 23)) } const disabledMinutes = (hour: number) => { if (hour === 17) { return makeRange(0, 29) } if (hour === 18) { return makeRange(31, 59) } return [] } const disabledSeconds = (hour: number, minute: number) => { if (hour === 18 && minute === 30) { return makeRange(1, 59) } return [] } </script>

三个函数的签名与调用约定如下(类型定义见 common/props.ts 与 props/shared.ts):

属性签名返回说明
disabledHours(role: string, comparingDate?: Dayjs) => number[]被禁用的小时数组role在区间模式中为'start'/'end',用于区分起始/结束面板
disabledMinutes(hour: number, role: string, comparingDate?: Dayjs) => number[]被禁用的分钟数组根据当前选中的小时动态决定禁用的分钟
disabledSeconds(hour: number, minute: number, role: string, comparingDate?: Dayjs) => number[]被禁用的秒数组根据小时和分钟组合动态决定禁用的秒

从实现上看,basic-time-spinner.vue通过getTimeLists(定义于 composables/use-time-picker.ts)将这些函数转化为每一列的可选项列表,被禁用的选项会加上is-disabledclass 且点击无效。上例的效果是:17:30 之后、18:30 之前的时间可选,其余时刻的时分秒均被置灰。

提示:在区间模式中,comparingDate参数还会携带当前正在比较的对面端点日期,可据此实现"结束时间不能早于开始时间"这类联动限制。

区间选择:任意时间范围

通过is-range属性可以让 TimePicker 切换为区间模式,一次选择起止两个时间点,输入框会显示为"起始时间 - 结束时间"的双输入形态。以下示例来自 docs/examples/time-picker/range.vue:

<template> <div class="demo-range"> <el-time-picker v-model="value1" is-range range-separator="To" start-placeholder="Start time" end-placeholder="End time" /> <el-time-picker v-model="value2" is-range arrow-control range-separator="To" start-placeholder="Start time" end-placeholder="End time" /> </div> </template> <script lang="ts" setup> import { ref } from 'vue' const value1 = ref<[Date, Date]>([ new Date(2016, 9, 10, 8, 40), new Date(2016, 9, 10, 9, 40), ]) const value2 = ref<[Date, Date]>([ new Date(2016, 9, 10, 8, 40), new Date(2016, 9, 10, 9, 40), ]) </script>

区间模式下的几个关键点:

  • v-model绑定的值必须是长度为 2 的数组,例如[Date, Date][number, number][string, string],分别对应绑定值为 Date 对象、时间戳、格式化字符串三种形态;
  • range-separator自定义两个输入框之间的分隔符,默认是'-'
  • start-placeholderend-placeholder分别设置起始框和结束框的占位文本;
  • arrow-control同样支持区间模式。

在源码中,is-range决定了两件事(见 time-picker.tsx):内部 type 标记为'timerange',面板组件切换为TimeRangePanel(time-picker-com/panel-time-range.vue);区间触发输入框则由 common/picker-range-trigger.vue 渲染。

Attributes 属性总览

以下属性表完整继承自官方文档,并补充了取值范围说明。除非特别标注版本,属性在当前版本中均可用:

名称说明类型默认值
model-value/v-model绑定值,若为数组则长度应为 2number/string/Date/[Date, Date]/[number, number]/[string, string]''
readonly是否只读booleanfalse
disabled是否禁用booleanfalse
editable输入框是否可编辑booleantrue
clearable是否显示清除按钮booleantrue
size输入框尺寸'large' \| 'default' \| 'small'
placeholder非区间模式的占位文本string''
start-placeholder区间模式起始框占位文本string
end-placeholder区间模式结束框占位文本string
is-range是否选择时间区间booleanfalse
arrow-control是否使用箭头按钮选择时间booleanfalse
popper-class下拉浮层自定义类名string''
popper-style下拉浮层自定义样式string/object
popper-options自定义 popper 配置项(基于 Popper.js 的Partial<PopperOptions>object{}
fallback-placements(2.8.4)浮层兜底位置列表Placement[]['bottom', 'top', 'right', 'left']
placement(2.8.4)浮层弹出位置Placementbottom
range-separator区间分隔符string'-'
format输入框中显示值的格式,参见 date-formatsstring
default-value日历默认日期(可选)Date/[Date, Date]
value-format绑定值的格式;不指定时绑定值为 Date 对象,参见 date-formatsstring
id原生 input 的idstring/[string, string]
name原生 input 的namestring''
aria-label(a11y,2.7.2)原生 input 的aria-labelstring
prefix-icon自定义前缀图标组件string/ComponentClock
clear-icon自定义清除图标组件string/ComponentCircleClose
disabled-hours指定不可选的小时数组(role: string, comparingDate?: Dayjs) => number[]
disabled-minutes指定不可选的分钟数组(hour: number, role: string, comparingDate?: Dayjs) => number[]
disabled-seconds指定不可选的秒数组(hour: number, minute: number, role: string, comparingDate?: Dayjs) => number[]
teleported下拉浮层是否传送(teleport)到 bodybooleantrue
tabindex输入框 tabindexstring/number0
empty-values(2.7.0)组件的空值集合,参见 config-provider 空值配置array
value-on-clear(2.7.0)清空时的返回值,参见 config-provider 空值配置string/number/boolean/Function
save-on-blur(2.13.4)聚焦时若未选择值,失焦是否自动填入当前时间booleantrue
label(a11y,已废弃)原生 input 的aria-label(已被aria-label取代)string

其中几个值得深入说明的属性:

formatvalue-format的区别。format只影响输入框的显示文本;value-format才决定v-model绑定值的数据形态。默认展示格式为HH:mm:ss(常量定义于 constants.ts),由DEFAULT_FORMATS_TIME提供。若设置了value-format(如'HH:mm:ss'),绑定值将变为字符串;若不设置,绑定值为Date对象。格式化与解析分别通过formatterparseDate完成,二者位于 utils.ts,底层依赖 dayjs 的customParseFormat插件(在 time-picker.tsx 中显式dayjs.extend(customParseFormat))。

popper-options/popper-class/popper-style/placement/fallback-placements这些属性共同控制下拉浮层的行为与外观。popperOptions在 time-picker.tsx 中通过provide(PICKER_POPPER_OPTIONS_INJECTION_KEY, props.popperOptions)注入到 Popper 体系;placementfallbackPlacements定义于 common/props.ts,其合法值取自 Popper.js 的placements枚举。注意:浮层相关链接指向外部文档,本文不展开,具体行为以 Popper.js 官方规范为准。

empty-valuesvalue-on-clear这两个 2.7.0 新增属性与全局 ConfigProvider 的空值策略联动,用于统一"哪些值算空值"以及"清空后回填什么值",适用于全项目需要统一空值语义的场景。

save-on-blur2.13.4 新增,默认true。它控制一个细节行为:聚焦时间面板但未做任何选择时,失焦后输入框是否自动填入当前系统时间。若设为false,失焦后输入框保持为空。

Events 事件

名称说明类型
change用户确认值时触发(val: number \| string \| Date \| [number, number] \| [string, string] \| [Date, Date]) => void
blur输入框失焦时触发(e: FocusEvent) => void
focus输入框聚焦时触发(e: FocusEvent) => void
clear(2.7.7)可清除的 TimePicker 中点击清除图标时触发() => void
visible-change下拉浮层出现/消失时触发(visibility: boolean) => void

change事件的值形态与value-format设置强相关:不设置value-format时回调中收到的是Date对象(区间模式为[Date, Date]),设置后则是格式化字符串或时间戳。visible-change常用于在面板展开/收起时联动其他 UI 逻辑,例如收起后同步外部统计或重置状态。

Exposes 暴露的方法

TimePicker 通过模板引用(template ref)暴露以下方法,可在父组件中通过ref获取组件实例后调用:

名称说明类型
focus聚焦 TimePicker 组件() => void
blur使 TimePicker 组件失焦() => void
handleOpen(2.2.16)打开 TimePicker 浮层() => void
handleClose(2.2.16)关闭 TimePicker 浮层() => void

这四个方法在 time-picker.tsx 中通过ctx.expose暴露,内部全部委托给公共Picker实例(commonPicker)的同名方法。典型用法示例:

<template> <el-time-picker ref="pickerRef" v-model="value" /> <el-button @click="pickerRef?.handleOpen()">打开时间面板</el-button> </template> <script lang="ts" setup> import { ref } from 'vue' import type { TimePickerInstance } from 'element-plus' const pickerRef = ref<TimePickerInstance>() const value = ref() </script>

源码结构解读:TimePicker 的分层设计

结合前文各部分,TimePicker 在仓库中的完整结构如下(packages/components/time-picker):

src/ ├── common/ # 公共逻辑 │ ├── picker.vue # 输入框 + 浮层 + 焦点管理 │ ├── picker-range-trigger.vue # 区间模式双输入触发框 │ └── props.ts # 组件全部默认属性定义 ├── composables/ # 组合式函数 │ ├── use-common-picker.ts # 公共 picker 逻辑 │ ├── use-time-panel.ts # 面板联动逻辑 │ └── use-time-picker.ts # 时/分/秒禁用列表计算 ├── props/ # 分块属性定义 │ ├── basic-time-spinner.ts │ ├── panel-time-picker.ts │ ├── panel-time-range.ts │ └── shared.ts # disabledTimeListsProps 等共享属性 ├── time-picker-com/ # 面板组件 │ ├── basic-time-spinner.vue # 时/分/秒滚动列核心 │ ├── panel-time-pick.vue # 单值面板 │ └── panel-time-range.vue # 区间面板 ├── constants.ts # 默认格式、注入 key 等常量 ├── time-picker.tsx # ElTimePicker 主组件 └── utils.ts # 格式化/解析/日期比较工具

值得注意的设计细节:

  1. 禁用列表的链式计算disabledMinutes接收disabledHours的选中结果,disabledSeconds再接收前两者的结果,逐级收敛可选范围,最终由getTimeLists汇总为三个列的禁用状态数组。
  2. 滚动与箭头双模式复用同一数据源basic-time-spinner.vue中滚动模式使用el-scrollbar渲染完整列表并支持滚轮,箭头模式则通过buildTimeList(utils.ts)只渲染当前值的前一个/当前/后一个三个候选值,配合v-repeat-click实现按住连加连减。
  3. 属性驱动的组件组合:主组件ElTimePicker只做"根据is-range选择面板组件"这一件事,其余全部逻辑下沉到公共Picker,这也解释了为何is-range可以在属性表中单独成行而面板切换对用户完全透明。
  4. 测试保障:仓库在 packages/components/time-picker/tests/time-picker.test.tsx 中对该组件的绑定、禁用、区间、事件等行为有完整的单元测试覆盖,可作为自定义扩展时的行为参照。

总结

Element Plus 的 TimePicker 以"任意时间选择 → 时间范围限制 → 区间选择"三个层次覆盖了绝大多数时间输入场景:基础用法配合arrow-control应对滚轮与按钮两种交互习惯;disabled-hours/minutes/seconds提供逐级精确的可选区间控制;is-range一键切换为起止时间双输入。配合format/value-format控制显示与绑定形态、save-on-blurempty-values等精细属性,以及focus/handleOpen等暴露方法,足以支撑表单校验、预约时段、排班配置等各类实战需求。

【免费下载链接】element-plus🎉 A Vue.js 3 UI Library made by Element team项目地址: https://gitcode.com/GitHub_Trending/el/element-plus

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

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

LoRA微调查询改写器:轻量高效提升RAG检索精度

1. 项目概述&#xff1a;为什么一个查询改写器值得用 LoRA 单独微调&#xff1f;你有没有遇到过这样的情况&#xff1a;在搭建 RAG 系统时&#xff0c;检索模块明明召回了三篇高度相关的文档&#xff0c;但最终大模型却生成了一段完全跑题的回答&#xff1f;或者用户输入“上个…

作者头像 李华
网站建设 2026/9/12 5:14:11

awesome-gpt-image-2:GPT-Image-2资源清单构建与实战指南

1. 内容整体设计与思路拆解1.1 为什么要做“awesome”系列资源清单做“awesome-gpt-image-2”这个项目&#xff0c;本质上不是开发一个工具&#xff0c;而是建一个信息枢纽。GPT-Image-2这个模型刚出来那阵子&#xff0c;市面上的信息极其分散&#xff1a;有官方文档、有社区评…

作者头像 李华
网站建设 2026/9/12 5:11:09

TypeScript中interface与type的核心区别与应用场景

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

作者头像 李华