HarmonyOS6 - 鸿蒙日历实战案例
开发环境为:
开发工具:DevEco Studio 6.0.1 Release
API版本是:API21
本文所有代码都已使用模拟器测试成功!
1. 最终效果

2. 需求说明
详细需求如下:
- 先要在页面中显示一个可以任意翻阅的日历,并显示公历和农历,还有常见的一些节气信息
- 对于给定的日期数组,需要在日历中对应的天中,标识出来,显示:已签到
- 当查看其他月份数据时,可以快速一键回到今天日期
- 在日历中,今天就直接显示:今天,不需要显示今天的日期
3. 实现思路
我们这里借助第三方组件库cjcalendar 实现我们上述需求
cjcalendar简介:
cjcalendar 是一款日常开发常用的日历组件,内部集成常规、单选、时间范围选择、多选、自定义日期每项显示等.
- 支持月视图、周视图显示
- 支持常规日历操作,同时支持单选、多选、一段时间选择
- 支持农历、节假日等
- 支持各种选中标记,文字标记、图片标记、自定义复杂标记
- 支持各个单元格自定义样式,每个单元格样式具备独立性
- 支持各种复杂场景的自定义,自定义背景层、主题日期内容显示层等
- 内置线型、面型等多种样式效果
- 支持设置日历主题色设置
- 后续规划:年视图、日视图、时间独立选择等
仓库网址:
https://ohpm.openharmony.cn/#/cn/detail/cjcalendar
4. 案例代码
开发思路如下:
- 引入日历组件:导入CJCalendar组件及相关类型定义,搭建基本日历框架,配置显示农历、节气等属性。
- 准备签到数据 :定义已签到日期数组(如
signDate),包含已签到的日期字符串(格式:YYYY-MM-DD)。 - 标记签到状态 :在
reBuildCellItem回调中,将每个日历日期格式化为相同格式,与签到数组比对,匹配则设置markText为"已签到"。 - 自定义样式 :通过
buildCellStyle设置日期标记样式(如红色文字),通过buildWeekTitleCell自定义星期标题样式(如周末特殊颜色)。
1. 依赖引入
要使用【cjcalendar】这个第三方组件库的话,我们需要在我们的工程中引入它,方法如下:

在工程根目录下执行下面命令:
ohpm install cjcalendar
执行成功后,打开项目根目录下的【oh-package.json5】文件,如下:

按照上面步骤确认下是否多出【"cjcalendar": "^2.3.5"】这个代码就可以了
2. 页面开发
页面代码如下:
js
import { CJCalendar, CJCellStyle, CJDateItem, OptMode } from 'cjcalendar';
/**
* Desc: 日历-案例
* Author: 波波老师(weixin: javabobo0513)
*/
@Entry
@Component
struct Page06 {
//已签到日期
@State signDate: Array<string> = [
'2026-01-2',
'2026-01-3',
'2026-01-4',
'2026-01-7',
'2026-01-8',
'2026-01-9',
'2026-01-12',
'2026-01-14',
'2026-01-15'
];
@Builder
BuildWeekTitleCell(week: string) {
Text(week)
.textAlign(TextAlign.Center)
.fontColor(week == '日' || week == '六' ? '#01acfc' : "#9E9E9E")
.fontSize(week == '日' || week == '六' ? 16 : 13)
.fontWeight(week == '日' || week == '六' ? 800 : 400)
.layoutWeight(1)
}
build() {
Column() {
//日历组件
CJCalendar({
// 普通模式
optMode: OptMode.NORMAL,
//标题背景色
titleBackgroundColor: '#ffffff',
//快速选择今天的文字颜色
fastTodayFontColor: '#ffffff',
//是否显示农历,默认:false
showLunar: true,
//是否显示折叠视图
isShowFoldView: false,
//是否显示节气,显示农历下才支持,默认:false
showJieQi: true,
//是否显示节日,显示农历下才支持,默认:false
showJieRi: true,
//快速选择今天的文字的背景颜色
fastTodayBackgroundColor: '#01acfc',
// startDate: new Date(2024, 11, 4),//限制选择的开始日期
//指定选择的开始日期为今天
// startDate: new Date(),
// endDate: new Date(2024, 11, 5),//限制选择的截止日期
//设置已签到日期的标记
reBuildCellItem: (cjDateItem: CJDateItem) => {
// 需要向 CJDateItem 中添加附加数据时,可是使用如下方式
cjDateItem.extras.test = "自定义附加属性" + cjDateItem.date
if (cjDateItem.isToday) {
cjDateItem.dateText = "今天"
}
let curentMonth = cjDateItem.month + 1;
let date = cjDateItem.fullYear + '-' + (curentMonth < 10 ? ('0' + curentMonth) : curentMonth) + '-' +
cjDateItem.date
console.log('date=============' + date)
let indexValue: number = this.signDate.indexOf(date);
if (indexValue > -1) {
//找到元素索引了
cjDateItem.markText = '已签到'
}
},
//自定义Cell样式风格
buildCellStyle: (item: CJDateItem) => {
let cjCellStyle: CJCellStyle = new CJCellStyle()
// 标注样式
cjCellStyle.markFontColor = "#ffff0000"
cjCellStyle.markFontSize = 10
cjCellStyle.markFontWeight = FontWeight.Bold
// 设置今天文字颜色
cjCellStyle.todayFontColor = '#00a9fa'
return cjCellStyle
},
// 自定义星期标题样式
buildWeekTitleCell: (week: string) => {
this.BuildWeekTitleCell(week)
}
})
}
.height('100%')
.width('100%')
}
}
直接将上面代码拷贝至你的页面中,使用预览器就可以看到效果了,签到日期在变量【signDate】集合中定义的,可以自行修改,看效果即可
在前后端项目中,后台接口返回当前用户已签到日期就可以了,就可以显示登录人签到历史数据在日历中直观展示出来的效果了
总结
CJCalendar日历组件使用总结
📌 核心要点
- 组件基础使用
- 引入
CJCalendar组件并配置基础属性 - 通过
OptMode.NORMAL设置普通模式 - 控制显示元素:农历、节气、节日等
- 数据绑定与标记
- 使用
reBuildCellItem回调处理每个日期项 - 将签到数据格式化为统一格式进行匹配
- 通过
markText属性标记特殊状态(如"已签到")
- 样式定制化
buildCellStyle:定制日期单元格样式buildWeekTitleCell:定制星期标题样式- 可灵活设置颜色、字体、大小等视觉属性
- 扩展功能
- 通过
extras属性添加自定义数据 - 支持限制选择日期范围
- 可控制折叠视图等高级功能
💡 关键技巧
- 日期格式统一处理确保匹配准确
- 利用回调函数实现动态内容渲染
- 样式与数据逻辑分离,便于维护
- 充分利用组件提供的丰富配置项
🔧 适用场景
- 签到打卡系统
- 活动日程展示
- 数据可视化日历
- 任务管理界面
该组件功能全面且高度可定制,通过合理配置可满足多种业务场景需求。