uni-app需自研签到日历,u-calendar的markList仅识别"YYYY-MM-DD"格式字符串;须转换后端日期、动态更新markList、用custom-item插槽自定义样式;点击签到应监听@select(uView 3.x/2.x)或插槽@tap;注意时区导致的日期偏移。

uni-app 没有内置签到日历组件,必须自己组合逻辑 + 渲染 + 状态管理,不能靠「加个属性就出红点」蒙混过关。
u-calendar 的 markList 为什么总不显示签到标记
根本原因是格式不对——markList 只认 "YYYY-MM-DD" 字符串,其他一律忽略。
- 后端返回的日期字段是
"2026-10-30T08:00:00Z"或"2026/10/30"?必须转:用date.toISOString().split('T')[0]或手动拼接year + '-' + (month + 1).toString().padStart(2, '0') + '-' + date.getDate() -
markList必须是数组,每个对象含date(字符串)和info(单字符,如"✓")或tip(底部文字) - 别写死在
data里:签到成功后要重新赋值this.markList = [...this.markList, { date: '2026-10-30', info: '✓' }],否则响应式不触发 - H5 端可能需加
v-if="markList.length"强制重绘;小程序端没问题,App 端部分版本需this.$forceUpdate()
uni-calendar 怎么自定义签到样式(已签/未签/禁用)
别碰 .uni-calendar__mark 类——它只控制默认小圆点,且跨端表现不一致。必须用 custom-item 插槽接管整个格子渲染。
- 插槽参数
item是一个对象,含date(Date 实例)、isCurrentMonth、isToday等字段 - 把
item.date格式化为"YYYY-MM-DD"字符串,再查是否在你的signList数组里(比如this.signList.includes(dateStr)) - 已签:渲染红色圆点
;未签但可点:加@click="handleSign(dateStr)";禁用(如昨天之后不可补签):加class="disabled"并阻止事件 - App 端 iOS 对
@click支持不稳定,统一用@tap+catchtouchmove防穿透
点击某天怎么真正触发签到而不是只选中日期
别监听 @change——它只返回当前月 { year, month },不是你点的那天。要捕获「点某一天」动作,得看 uView 版本:
- uView 3.x:用
@select,参数是{ date: "2026-10-30" },直接拿去调接口 - uView 2.x:用
@confirm不行(只点确定按钮才触发),必须用@select(注意:2.x 文档没写但实际支持) - uni-calendar 官方组件:没有
@select,只能靠custom-item插槽里的@tap拿item.date自己处理 - 签到成功后,记得更新本地状态(
signList.push(dateStr))并刷新日历视图,否则下次打开还是旧状态
最易被忽略的点:时区和日期边界。后端按 UTC 返回的 "2026-10-30",在东八区用户手机上可能是 10 月 31 日凌晨,导致「今天」判断错乱。建议统一用 new Date().toLocaleDateString('sv-SE')(返回标准 ISO 字符串)生成今日日期,别依赖服务端传来的“今天”。











