uni-app全能日历组件,支持农历、酒店预订、打卡签到、价格日历多种场景
一、uView Pro 的 Calendar 日历组件
在 uni-app 开发中,日期选择是一个高频需求场景。无论是酒店预订的入住离店时间选择、电商平台的商品预约、还是日常应用的打卡签到,一个功能完善、体验优秀的日历组件都是必不可少的。
uView Pro 作为 uni-app 生态中备受关注的 Vue3 组件库,其 Calendar 日历组件 经过了多个版本的迭代优化,从最初的基础日期选择,逐步演进为支持农历显示、打卡签到、节假日标记、自定义价格日历等丰富功能的综合型组件。
本文将深入解析 uView Pro Calendar 组件的核心特性、实现原理以及实际应用场景,帮助你快速掌握这个强大的日期选择利器。
二、组件概览:功能特性总览

uView Pro 的 Calendar 日历组件具有以下核心特性:
基础功能
-
✅ 支持单日期选择和日期范围选择两种模式 -
✅ 底部弹窗和页面嵌入两种展示方式 -
✅ 年月切换导航,支持自定义年份范围 -
✅ 日期范围限制,防止选择无效日期
进阶功能
-
✅ 农历显示支持,自动计算农历日期 -
✅ 打卡签到模式,支持已打卡/未打卡状态展示 -
✅ 节假日和加班日标记,显示”休”/”班”标识 -
✅ 内置中国传统节日,支持自定义节日配置 -
✅ 自定义日期内容插槽,适用于价格日历等场景
交互优化
-
✅ 默认选中今天,支持指定默认日期 -
✅ 只读模式,禁止日期选择 -
✅ 选中效果可配置,适应不同视觉需求
三、基础使用:快速上手
3.1 单日期选择模式
单日期选择是最常用的场景,比如选择生日、预约日期等。

<template><view><u-calendarv-model="show"mode="date" @change="onChange"></u-calendar><u-button @click="show = true">选择日期</u-button></view></template><scriptsetuplang="ts">import { ref } from'vue'import type { CalendarChangeDate } from'uview-pro/types/global'const show = ref(false)functiononChange(e: CalendarChangeDate) {console.log('选择的日期:', e.result)console.log('星期:', e.week)console.log('是否今天:', e.isToday)}</script>
回调参数说明:
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3.2 日期范围选择模式
范围选择适用于酒店预订、行程规划等需要起止时间的场景。

<template><u-calendarv-model="show"mode="range"start-text="入住"end-text="离店" @change="onRangeChange" ><template #tooltip><viewclass="tip">请选择入住和离店时间</view></template></u-calendar></template><scriptsetuplang="ts">import { ref } from'vue'import type { CalendarChangeRange } from'uview-pro/types/global'const show = ref(false)functiononRangeChange(e: CalendarChangeRange) {console.log('入住日期:', e.startDate)console.log('离店日期:', e.endDate)console.log('共', e.endDay - e.startDay + 1, '晚')}</script>
范围模式回调参数:
|
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
四、进阶功能详解
4.1 农历显示
Calendar 组件内置了农历计算功能,开启后会自动显示农历日期。

<u-calendarv-model="show"mode="date":show-lunar="true" @change="onLunarChange"></u-calendar>
开启农历后,回调参数会增加 lunar 对象:
{ day: 15, month: 6, result: "2024-06-15", lunar: { dayCn: '初十', // 农历日 monthCn: '五月', // 农历月 year: 2024, // 农历年 weekCn: "星期六"// 农历星期 }}
农历显示会自动处理闰月、大小月等复杂逻辑,无需开发者关心底层实现。
4.2 页面嵌入模式
除了弹窗模式,组件还支持直接嵌入页面显示,适用于需要常驻展示日历的场景。
<template><viewclass="calendar-page"><u-calendar:is-page="true"mode="date" @change="onChange" ></u-calendar></view></template>
页面模式的特点:
-
不显示弹窗和确定按钮 -
选择日期后自动触发 change事件 -
支持所有其他功能(农历、打卡、节假日等)


4.3 打卡签到模式
打卡签到日历也是近期咨询我比较多的功能,Calendar 组件专门为此设计了打卡模式。

<template><u-calendar:is-page="true":checkin-mode="true":checked-dates="checkedDates":today-checked="todayChecked" ></u-calendar></template><scriptsetup>import { ref } from'vue'// 已打卡日期列表const checkedDates = ref(['2024-01-01', '2024-01-02', '2024-01-03','2024-01-05'])// 今日打卡状态(优先级高于自动判断)const todayChecked = ref(true)</script>
打卡模式的显示规则:
-
今日已打卡:绿色圆形背景,显示白色对勾 -
其他已打卡日期:橙色圆形背景,显示日期 -
未打卡日期( checkin-mode为 true 时):灰色圆形背景
颜色自定义:
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
4.4 节假日与加班日标记
组件支持显示节假日和加班日标记,方便用户了解日期属性。
<template><u-calendar:is-page="true":holidays="holidays":workdays="workdays" ></u-calendar></template><scriptsetup>import { ref } from'vue'// 节假日(元旦假期)const holidays = ref(['2024-01-01', '2024-01-02'])// 加班日(调休上班)const workdays = ref(['2024-01-06', '2024-01-07'])</script>
显示效果:
-
节假日:日期右上角显示红色”休”字 -
加班日:日期右上角显示蓝色”班”字 -
选中状态下,”休”/”班”字变为白色


4.5 节日显示
组件内置了中国传统节日,同时支持自定义节日配置。
内置节日(show-festival 为 true 时自动显示):
-
元旦(1月1日) -
情人节(2月14日) -
妇女节(3月8日) -
植树节(3月12日) -
愚人节(4月1日) -
劳动节(5月1日) -
青年节(5月4日) -
儿童节(6月1日) -
建党节(7月1日) -
建军节(8月1日) -
教师节(9月10日) -
国庆节(10月1日) -
光棍节(11月11日) -
圣诞节(12月25日)
自定义节日:
<template><u-calendar:is-page="true":show-festival="true":festivals="customFestivals" ></u-calendar></template><scriptsetup>import { ref } from'vue'const customFestivals = ref({// 每年固定节日(MM-DD 格式)'04-04': '清明节','05-05': '端午节','08-15': '中秋节',// 特定年份节日(YYYY-MM-DD 格式)- 优先级更高'2025-04-04': '清明节(2025)',// 覆盖内置节日(传入空字符串不显示)'02-14': '',})</script>
优先级规则:
-
特定年份格式( YYYY-MM-DD)优先级最高 -
每年固定格式( MM-DD)次之 -
内置节日优先级最低
4.6 自定义日期内容:价格日历
通过 date 插槽,可以完全自定义每个日期的显示内容,常用于电商价格日历场景。

<template><u-calendar:is-page="true"mode="date":use-date-slot="true" ><template #date="{ date }"><text:class="getPriceClass(date)"> {{ getPriceText(date) }}</text></template></u-calendar></template><scriptsetup>import { ref } from'vue'// 价格数据const priceMap = ref({'2024-01-01': 299,'2024-01-02': 399,'2024-01-03': 359,// ...})functiongetPriceText(date) {if (date.isToday) return'今天'const price = priceMap.value[date.date]return price ? `¥${price}` : ''}functiongetPriceClass(date) {if (date.isSelected) return'price-selected'if (date.isToday) return'price-today'return'price-normal'}</script><stylescoped>.price-today {color: #19be6b;font-weight: bold;}.price-normal {color: #909399;font-size: 22rpx;}.price-selected {color: #ffffff;}</style>
插槽作用域参数:
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
五、核心实现原理浅析
5.1 日历渲染逻辑
Calendar 组件的日历渲染基于以下核心算法:
// 获取某月天数functiongetMonthDay(year: number, month: number) {returnnewDate(year, month, 0).getDate()}// 获取某月第一天星期几(0-6)functiongetWeekday(year: number, month: number) {let date = newDate(`${year}/${month}/01 00:00:00`)return date.getDay()}
渲染流程:
-
计算当月第一天是星期几,生成前置空白格子 -
计算当月总天数,生成日期格子 -
根据选中状态计算每个格子的样式 -
如果有农历,调用农历转换库计算农历日期
5.2 农历计算
组件使用了独立的农历计算工具 Calendar.solar2lunar,将公历日期转换为农历:
functiongetLunar(year: any, month: any, day: any) {const val = Calendar.solar2lunar(year, month, day)return { dayCn: val.IDayCn, // 农历日(初十、廿三等) monthCn: val.IMonthCn, // 农历月(正月、五月等) weekCn: val.ncWeek, // 农历星期 day: val.lDay, // 农历日数字 month: val.lMonth, // 农历月数字 year: val.lYear // 农历年 }}
5.3 范围选择逻辑
范围选择采用两次点击确定起止时间的交互方式:
functiondateClick(dayIdx: number) {const d = dayIdx + 1const date = `${year.value}-${month.value}-${d}`if (props.mode == 'range') {// 判断是设置开始日期还是结束日期const compare = newDate(date).getTime() < newDate(startDate.value).getTime()if (isStart.value || compare) {// 设置开始日期 startDate.value = date isStart.value = false } else {// 设置结束日期 endDate.value = date isStart.value = true// 触发回调if (props.isPage) btnFix(true) } }}
六、实际应用场景
6.1 酒店预订日历
<u-calendarv-model="show"mode="range"start-text="入住"end-text="离店":min-date="minDate":max-date="maxDate" @change="onDateChange"><template #tooltip><viewclass="hotel-tip"><text>请选择入住和离店日期</text><textclass="sub">入住时间14:00后,离店时间12:00前</text></view></template></u-calendar>
6.2 健身打卡应用
<u-calendar:is-page="true":checkin-mode="true":checked-dates="monthCheckins":today-checked="todayChecked":show-lunar="true" @change="onCheckin"></u-calendar>
6.3 航班价格日历
<u-calendar:is-page="true"mode="date":use-date-slot="true":default-select-today="false":is-active-current="false"><template #date="{ date }"><viewclass="flight-price"><textclass="day">{{ date.day }}</text><textclass="price"v-if="getPrice(date.date)"> ¥{{ getPrice(date.date) }}</text></view></template></u-calendar>
6.4 日程管理应用
<u-calendar:is-page="true":show-festival="true":festivals="customFestivals":holidays="holidays":workdays="workdays":default-date="selectedDate" @change="onSelectDate"></u-calendar>
七、API 完整参考
Props 属性
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
|
|
date 单选 / range 范围 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Events 事件
|
|
|
|
|---|---|---|
|
|
|
|
Slots 插槽
|
|
|
|---|---|
|
|
|
|
|
|
❝
更多功能及用法参考 uView Pro 官方文档 https://uviewpro.cn
八、总结与建议
uView Pro 的 Calendar 日历组件是一个功能全面、设计精良的日期选择解决方案。从基础的单日期选择到复杂的打卡签到、价格日历,这些都能轻松应对。
使用建议:
-
选择合适的展示模式:弹窗模式适合临时选择,页面模式适合常驻展示 -
合理利用默认选中:通过 default-date或default-select-today提升用户体验 -
注意日期格式:所有日期参数统一使用 YYYY-MM-DD格式 -
自定义插槽优先级:使用 date插槽时会覆盖农历、节日等默认显示 -
打卡模式注意: today-checked优先级高于checkedDates的自动判断
功能使用注意:
-
如需农历功能,请确保使用支持该功能的版本 -
如需打卡签到、节假日、自定义插槽等高级功能,请使用 uView Pro 最新版本
如果你正在开发 uni-app 项目,需要一个功能强大、易于定制的日历组件,uView Pro 的 Calendar 值得一试,快来体验一下。
九、资源
-
📚 uView Pro 官方文档:https://uviewpro.cn -
📦 开源地址:https://github.com/anyup/uView-Pro -
💬 技术交流:如有问题欢迎留言讨论
注意:本文基于 uView Pro v0.5.17 版本编写,部分功能可能需要更新版本支持。
以上功能,可以直接进入uView Pro 小程序体验:
uView Pro 开源组件使用交流:


夜雨聆风