Varlet 日期选择器(DatePicker)完全指南:从基本使用到源码级原理 UI组件前端【免费下载链接】varletA Vue3 component library based on Material Design 2 and 3, supporting mobile and desktop.项目地址https://gitcode.com/gh_mirrors/va/varlet点击查看免费下载导读本文围绕 Varlet 组件库中的var-date-picker日期选择器展开系统讲解其在单组件场景下选择日期、月份、年份及对应范围的完整用法覆盖多选、范围选择、日期限制、标题与插槽定制等全部官方能力并深入组件源码DatePicker.vue、三个面板组件、props.ts与测试用例index.spec.js说明其底层实现逻辑。读完本文你将能熟练使用该组件的全部属性、事件、方法、插槽与样式变量并理解面板切换、预览状态与限制校验的实现机制。介绍var-date-picker用于选择日期date、月份month、年份year或对应的范围。组件整体由顶部标题区可隐藏、中部面板区与底部操作插槽区组成面板头部提供年/月切换箭头点击年份或月份文字可分别切换到年份面板或月份面板标题区同样支持点击切换面板视图。组件的源码入口位于 packages/varlet-ui/src/date-picker由 DatePicker.vue 作为容器内部组合了DayPickerPanelDayPickerPanel.vue、MonthPickerPanelMonthPickerPanel.vue、YearPickerPanelYearPickerPanel.vue与PanelHeaderPanelHeader.vue四个子组件。基本使用日期面板头部的年份和月份可分别点击以切换到年份或月份面板。通过v-model绑定一个字符串类型的日期值格式为YYYY-MM-DDscript setup import { ref } from vue const date ref(2021-04-08) /script template var-date-picker v-modeldate / /template从源码可见v-model对应的modelValue属性支持String | Arraystring两种形态props.ts具体形态由multiple/range属性决定。组件通过onUpdate:modelValue监听器在每次选择时写回新值并同步触发change事件DatePicker.vue。多选通过multiple属性支持选择多个日期此时date为一个字符串数组script setup import { ref } from vue const date ref([]) /script template var-date-picker v-modeldate multiple / /template多选模式下再次点击已选中的值会将其从数组中移除切换式选中。源码中的updateMultiple先对已有值按对应格式做格式化与查重命中则splice删除、未命中则push追加最后写回模型并触发changeDatePicker.vue。同时syncMultipleValue在同步外部传入的数组时会使用uniq去重并过滤掉Invalid Date这类非法值DatePicker.vue。测试用例datePicker multiple也验证了点击三次追加、再次点击删除的完整行为index.spec.js。选择范围通过range属性选择一个范围绑定值格式为[start, end]元素格式随type变化YYYY/YYYY-MM/YYYY-MM-DDscript setup import { ref } from vue const date ref([2021-04-08, 2021-04-20]) const month ref([2021-02, 2021-05]) const year ref([2021, 2025]) /script template var-date-picker typedate v-modeldate range / var-date-picker typemonth v-modelmonth range / var-date-picker typeyear v-modelyear range / /template范围选择的交互是两次点击完成一个区间第一次点击将起始值写入第二次点击补全结束值。源码updateRange中若起始值晚于结束值dayjs(nextRangeValues[0]).isAfter(nextRangeValues[1])会自动交换为[end, start]顺序DatePicker.vue。测试用例datePicker range传入乱序的[2021-05-19, 2021-05-18]后仍能正确渲染并输出正序区间index.spec.js。标题区范围模式下显示为start ~ end的拼接文本。日期限制通过min和max属性控制可选择日期的边界使用allowed-dates属性进一步限制可选择的值。三个限制维度取交集日期必须同时满足 min、 max且通过allowed-dates回调回调参数格式随type变化YYYY/YYYY-MM/YYYY-MM-DDscript setup import { ref } from vue const date ref(2020-11-11) const allowedDates val parseInt(val.split(-)[2], 10) % 2 1 /script template var-date-picker v-modeldate min2020-10-15 max2021-01-15 :allowed-datesallowedDates / /template上面示例中allowed-dates通过判断日期字符串第三段日是否为奇数实现了只允许选择单号日期的约束。源码中的isSelectableDate是统一的限制校验入口分别用isSameOrBefore(dayjs(max), unit)、isSameOrAfter(dayjs(min), unit)在对应时间粒度day/month/year上做边界比较再叠加allowedDates(dateValue)的布尔结果DatePicker.vue。三个面板组件在选择时都会先调用该校验不满足则直接return不会触发任何模型更新或 change 事件——测试用例datePicker does not emit change when choosing disabled value对此有专门验证index.spec.js。需要注意在typedate模式下allowed-dates只拦截具体日期的选择不会阻断面板在年份/月份间的自由切换此时切换只更新预览状态而不写回模型详见测试用例datePicker allowedDates does not block year or month navigation in date typeindex.spec.js。隐藏标题通过show-title属性控制是否显示顶部标题区域script setup import { ref } from vue const date ref(2021-04-08) /script template var-date-picker v-modeldate :show-titlefalse / /template从模板看showTitle为false时整个.var-date-picker__title节点不会渲染同时根节点会追加--no-title修饰类DatePicker.vue。在样式上该修饰类会把面板区高度向上补足calc(var(--date-picker-body-height) var(--date-picker-header-padding-top-no-title))避免隐藏标题后面板高度塌陷date-picker.less。测试用例datePicker showTitle验证了隐藏标题后标题节点消失而面板头部仍然存在index.spec.js。操作插槽通过actions插槽可以自定义底部操作区域。插槽内可通过组件实例方法resetPreview将面板视图重置到当前绑定值对应的位置没有有效绑定值时回退到fallback-view-date或今天script setup import { ref } from vue const date ref(2021-04-08) const datePicker ref() /script template var-date-picker refdatePicker v-modeldate template #actions var-button tonal typeprimary clickdatePicker.resetPreview() 重置视图 /var-button /template /var-date-picker /templateresetPreview的实现逻辑是先关闭年份/月份面板回到日期面板再根据当前modelValue重新同步预览年月范围与多选模式下取数组中第一个合法值作为预览源DatePicker.vue。测试用例datePicker resetPreview演示了在切换到 2022 年 5 月并打开年份面板后调用resetPreview视图立即回到绑定值 2021 年 4 月、且不会触发update:modelValueindex.spec.js。月份选择器将type设置为month可以选择年份和月份面板左侧的年份切换器用于切换或选择年份script setup import { ref } from vue const date ref(2021-04) /script template var-date-picker typemonth v-modeldate elevation / /templatetypemonth时绑定值格式为YYYY-MM。月份面板在日期面板内点击月份文字或直接作为独立选择器出现作为独立选择器时点击某个月份即完成选择并写回模型作为日期面板的中间态时点击月份仅更新预览月份并关闭月份面板DatePicker.vue。年份选择器将type设置为year可以直接选择年份script setup import { ref } from vue const date ref(2021) /script template var-date-picker typeyear v-modeldate / /templatetypeyear时绑定值格式为YYYY。年份面板以 100 年为一页进行分页展示源码yearList计算Math.floor(preview / 100 page) * 100得到页首年份YearPickerPanel.vue且挂载时会调用scrollToView将选中年份滚动到面板可见区域YearPickerPanel.vue。API 详解属性Props参数说明类型默认值v-model选中值格式随type变化YYYY/YYYY-MM/YYYY-MM-DDmultiple或range时为数组string[] | stringundefinedtype选择器类型可选值为date month yearstringdateallowed-dates限制可以选择的值参数格式随type变化YYYY/YYYY-MM/YYYY-MM-DDfunction-color选择器的颜色string-title-color标题背景色。如果未指定将使用color属性或默认颜色string-hint选择器提示语未设置时会根据type推导string-elevation海拔高度可选值为truefalse和0-24的等级string | number | booleanfalsebutton-elevationButton 的海拔高度string | number | booleantruefirst-day-of-week设置一周的第一天从周日的 0 开始string | number0min允许的最小值格式随type变化YYYY/YYYY-MM/YYYY-MM-DDstring-max允许的最大值格式随type变化YYYY/YYYY-MM/YYYY-MM-DDstring-show-current是否显示当前日期booleantrueshow-title是否显示顶部标题区域booleantruereadonly是否只读booleanfalsemultiple是否支持选择多个日期booleanfalserange是否支持选择一个范围booleanfalsefallback-view-date自 3.15.2在没有可用选中值时控制面板视图回退到的日期不会写回v-modelstring-以上默认值与 props.ts 中的属性定义完全一致。几个值得展开的细节hint的推导逻辑未设置hint时组件根据type自动取datePickerYearHint/datePickerMonthHint/datePickerHint三个多语言文案之一DatePicker.vue。测试用例datePicker should infer hint from type验证了year/month/date三种类型分别显示选择年份/选择月份/选择日期index.spec.js。elevation与button-elevation前者作用于整个选择器容器调用formatElevation(elevation, 2)生成海拔类后者透传给三个面板内部的var-button见 DayPickerPanel.vue 的:elevationpanelProps.buttonElevation。fallback-view-date的边界当modelValue为空multiple/range为空数组或未绑定值时面板初始定位到该日期所在的年/月但不会写回v-model。实现上getFallbackDate会先尝试格式化校验传入的兜底日期非法则回退到当天DatePicker.vue。测试用例datePicker fallbackViewDate should control initial panel when modelValue is empty用fallbackViewDate: 2026-04-01验证了初始面板定位到 2026 年 4 月、同时selectionState保持undefined、不触发update:modelValueindex.spec.js。事件Events事件名说明回调参数preview面板视图切换时触发。dayOfMonth为当前选中的月内日期没有可用选中日期时为undefinedyear: numbermonth: numberdayOfMonth?: numberchange日期改变时触发value: string \| string[]preview事件由emitPreview统一发出将预览年份、预览月份转为数字以及仅 date 类型下才有的选中日传入回调DatePicker.vue。测试用例datePicker month type should open year panel from header year验证了在月份面板切换年份后onPreview收到(2000, 1, undefined)且change/update:modelValue均不被触发index.spec.js——这体现了预览切换与值变更两条通道的严格分离。方法Methods方法名说明参数返回值resetPreview自 3.19.0将面板视图重置到当前绑定值对应的位置。没有有效绑定值时会使用fallback-view-date或今天--插槽Slots插槽参数中weekIndex表示一周的第n天从周日的0开始对应WeekHeader [0...6]的定义见 constants.ts。名称说明参数year自定义typeyear时的标题文字year: YYYYmonth自定义typemonth时的标题文字year: YYYYmonth: MMdate自定义typedate时的标题文字year: YYYYmonth: MMdate: DDweek: weekIndexrange自定义范围选择时的标题文字choose: [startDate, endDate]元素格式随type变化YYYY/YYYY-MM/YYYY-MM-DDmultiple自定义多选时的标题文字choose: string[]元素格式随type变化YYYY/YYYY-MM/YYYY-MM-DDactions自定义操作面板-标题插槽的渲染位置在 DatePicker.vue组件按type与选择模式单值 /range/multiple选择对应插槽未提供插槽内容时回退显示内置标题如中文环境下的04-08 周四、范围模式的2021-04-08 ~ 2021-04-20、多选模式的3 项已选等见 DatePicker.vue。样式变量CSS Variables以下为组件使用的 CSS 变量可以通过 StyleProvider 组件源码位于 packages/varlet-ui/src/style-provider或直接在组件根节点覆盖实现样式定制。变量定义在 date-picker.less 的:root中。变量名默认值--date-picker-border-radius4px--date-picker-font-sizevar(--font-size-md)--date-picker-min-width290px--date-picker-main-colorrgba(0, 0, 0, .87)--date-picker-title-hint-colorvar(--color-on-surface-variant)--date-picker-title-hint-font-sizevar(--font-size-md)--date-picker-title-height105px--date-picker-title-padding20px 20px 16px--date-picker-title-background#fff--date-picker-title-colorrgba(0, 0, 0, .87)--date-picker-title-date-height48px--date-picker-title-date-font-size34px--date-picker-title-date-font-weight500--date-picker-title-date-range-font-size20px--date-picker-title-date-justify-contentnormal--date-picker-header-arrow-filteropacity(1)--date-picker-body-background-color#fff--date-picker-body-height304px--date-picker-body-padding-horizontal12px--date-picker-body-padding0 var(--date-picker-body-padding-horizontal) 16px--date-picker-header-padding0 0 16px--date-picker-header-padding-top-no-title20px--date-picker-actions-padding10px 20px 20px--date-picker-header-color#555--month-picker-padding0 12px--month-picker-item-width32%--month-picker-item-height46px--month-picker-item-button-max-width140px--month-picker-item-button-font-weightnormal--year-picker-padding0 12px--year-picker-item-width32%--year-picker-item-height46px--year-picker-item-button-max-width140px--year-picker-item-button-font-weightnormal--day-picker-content-item-width14.28%--day-picker-content-item-min-height21px--day-picker-content-item-font-sizevar(--font-size-md)--day-picker-content-item-padding2px 0--day-picker-content-item-button-width32px--day-picker-content-item-button-height32px--day-picker-content-item-button-font-sizevar(--font-size-md)--day-picker-head-item-colorrgba(0, 0, 0, 0.38)--day-picker-head-item-font-sizevar(--font-size-md)--day-picker-head-item-padding8px 0--day-picker-head-item-font-weightnormal--day-picker-adjacent-item-colorrgba(0, 0, 0, 0.38)分组说明--date-picker-*系列控制整体容器、标题区与面板区的布局和配色--month-picker-*/--year-picker-*控制月份、年份面板中按钮的尺寸与字重--day-picker-*控制日面板的表头与日期格。例如将--day-picker-content-item-button-width与--day-picker-content-item-button-height从32px调大即可整体放大可点击的日期按钮。源码结构组件是如何工作的面板体系与预览 / 选中双状态从 DatePicker.vue 的模板与setup可以看出组件内部维护两类状态选中状态selectionState与v-model严格同步保存选中年/月/日、多选数组、范围数组等类型定义见 types.ts预览状态previewYear/previewMonth仅描述当前面板停在哪一年哪一月可独立于绑定值自由切换。两者通过syncFromModelValue在模型变化时对齐通过emitPreview/emitModelValueChange分别对外广播。watch监听modelValue时通过shouldKeepPreviewOnModelValueChange标记决定是否连带同步预览DatePicker.vue——这保证了在日期类型中切换面板、或多选/范围中连续选择时面板不会因模型回写而跳回初始位置。面板切换与 42 格日面板switchPanel控制showYearPanel/showMonthPanel两个开关结合type计算当前panelType从而在三个面板组件间切换DatePicker.vue。PanelHeader提供上一月/下一月、上一年/下一年的箭头按钮以及打开年份/月份面板的文字按钮PanelHeader.vue。日面板的网格算法在 DayPickerPanel.vue固定渲染6 行 × 7 列 42个格子先根据当月 1 号的星期与firstDayOfWeek计算前置补位数量leadingCount再在月末追加后置补位trailingCount相邻月份的日期同样可点击带monthOffset标记选中后会自动把预览切换到对应月份。测试用例datePicker passes padded dates for every day panel cell断言allowedDates恰好被调用 42 次且传入值包含2021-02-28上月补位与2021-04-10下月补位全部符合^\d{4}-\d{2}-\d{2}$格式index.spec.js。firstDayOfWeek的实现同样在日面板根据WeekHeader中找到指定索引并做环形重排sortWeekListDayPickerPanel.vue。测试用例datePicker firstDayOfWeek传入3后断言表头第一个元素为三index.spec.js。格式与常量组件的时间格式、类型与星期定义集中在 constants.tsDatePickerFormatsYYYY/YYYY-MM/YYYY-MM-DD三种格式与type一一对应constants.tsDatePickerTypesdate/month/yearMonthList01~12的月份常量数组WeekHeader0~6的星期索引。所有日期解析与格式化均基于统一的 dayjs 实例createDayjs非法值会输出Invalid Date并被组件拦截invalidFormatDate检测到后会向控制台输出modelValue is an Invalid Date的警告DatePicker.vue。测试用例datePicker value legal验证了multiple与数组/字符串类型不匹配、非法日期字符串等场景会抛出错误提示index.spec.js。只读与交互细节readonlyselectDayFromPanel/selectMonthFromPanel/selectYearFromPanel三个选择入口的第一步都是if (readonly) return因此只读模式下点击任何格子都不会改变模型DatePicker.vue。测试用例datePicker readonly对月、日两种类型均验证了点击后绑定值保持不变index.spec.js。pointerdown拦截根节点绑定了pointerdown.capture.prevent防止拖拽或长按等手势触发文本选择等默认行为DatePicker.vue并有专门的测试用例验证index.spec.js。title-color优先级标题背景取titleColor || colorDatePicker.vue测试用例datePicker titleColor验证了传入red后标题背景为red且后续修改会同步更新index.spec.js。min/max动态更新面板会对min、max的变化重新渲染测试用例datePicker rerender date panel when max or min changesindex.spec.js。版本变更说明自3.19.0起以下属性和 CSS 变量已移除升级时需注意清理已移除属性已移除属性touchable已移除变量已移除变量--date-picker-title-year-font-size--date-picker-title-year-font-weight--date-picker-title-year-margin-bottom--date-picker-title-year-min-heighttouchable原用于控制是否允许触控交互其移除意味着组件默认即支持完整触控操作无需再显式开启。四个被移除的标题年份样式变量则随 3.19.0 新增的resetPreview方法重构一并清理标题年份样式现在统一由--date-picker-title-date-*系列变量管理。结语Varlet 的var-date-picker是一个典型的属性少、能力全的移动端友好日期选择组件通过type一个维度即可在日期、月份、年份三种粒度间切换multiple/range两个开关即可覆盖多选与区间场景min/max/allowed-dates三层校验让业务约束可精确表达。理解其预览状态与选中状态分离的核心设计后无论是用preview事件监听面板变化、用actions插槽做自定义确认流程还是通过样式变量做主题适配都能做到心中有数。若要进一步阅读可参考组件完整源码 packages/varlet-ui/src/date-picker 及其 1048 行测试套件 index.spec.js运行示例则位于 example/index.vue。赞分享UI组件前端【免费下载链接】varletA Vue3 component library based on Material Design 2 and 3, supporting mobile and desktop.项目地址https://gitcode.com/gh_mirrors/va/varlet点击查看免费下载相关推荐Vant DatePicker 日期选择器完全指南从基础用法到源码级原理Vant DatePicker 日期选择器完全指南从基础用法到源码级原理 Vant 的 DatePicker 组件用于在移动端选择年、月、日是一个基于 Pi前端UI组件Vant DatePicker 日期选择器完全指南从基础用法到源码级原理剖析Vant DatePicker 日期选择器完全指南从基础用法到源码级原理剖析 日期选择器是移动端表单场景中使用频率最高的组件之一。本文以 Vant 4 的 D前端UI组件cube-ui DatePicker 日期选择器完全指南从基本用法到源码级实现解析cube ui DatePicker 日期选择器完全指南从基本用法到源码级实现解析 导读 cube ui 的 DatePicker 组件用于在移动端场景下选择前端UI组件移动开发上一篇从理论到实践ESC-50数据集环境声音分类项目全解析下一篇OptiScaler终极指南让所有显卡都能体验DLSS级画质提升创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考