Grid 构建月历网格:7 列模板 + 日期占位算法

前言

在"海风日记"的日历页中,月历网格使用 Grid 组件实现,通过 7 列模板、日期占位算法和条件渲染,实现了完整的月历展示功能。

本文将从 CalendarTab.ets 源码出发,深入讲解 Grid 构建月历的实现,包括列模板配置、日期偏移计算和条件渲染。


一、月历网格实现

1.1 基本布局

typescript 复制代码
Grid() {
  // 空白填充(月份第一天的偏移)
  ForEach(this.createPlaceholderArray(this.getFirstDayOfMonth()), (i) => {
    GridItem() {
      Column().width('100%').height(52)
    }
  })

  // 日期格子
  ForEach(this.createDayArray(this.getDaysInMonth()), (day) => {
    GridItem() {
      // 日期内容
    }
  })
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr 1fr 1fr')  // 7 列
.rowsGap(0)
.columnsGap(0)

二、日期计算工具函数

2.1 获取当月天数

typescript 复制代码
private getDaysInMonth(year: number, month: number): number {
  return new Date(year, month + 1, 0).getDate()
}

2.2 获取当月第一天是星期几

typescript 复制代码
private getFirstDayOfMonth(year: number, month: number): number {
  return new Date(year, month, 1).getDay()  // 0=Sunday, 1=Monday...
}

2.3 数组生成函数

typescript 复制代码
// 生成 1..count 的数字数组
private createDayArray(count: number): number[] {
  const result: number[] = []
  for (let i = 1; i <= count; i++) { result.push(i) }
  return result
}

// 生成 0..count-1 的占位数组
private createPlaceholderArray(count: number): number[] {
  const result: number[] = []
  for (let i = 0; i < count; i++) { result.push(i) }
  return result
}

三、日期占位算法

3.1 算法原理

复制代码
假设 2025年4月1日是星期二(getDay() = 2)
需要 2 个空白占位格(星期日、星期一)

Grid 7列:
| 空 | 空 | 1  | 2  | 3  | 4  | 5  |
|  6 |  7 |  8 |  9 | 10 | 11 | 12 |
| 13 | 14 | 15 | 16 | 17 | 18 | 19 |
| 20 | 21 | 22 | 23 | 24 | 25 | 26 |
| 27 | 28 | 29 | 30 |    |    |    |

3.2 完整实现

typescript 复制代码
Grid() {
  // 空白填充
  ForEach(
    this.createPlaceholderArray(this.getFirstDayOfMonth(this.curYear, this.curMonth)),
    (i: number) => {
      GridItem() {
        Column().width('100%').height(52)
      }
    },
    (i: number) => `placeholder_${i}`
  )

  // 日期格子
  ForEach(
    this.createDayArray(this.getDaysInMonth(this.curYear, this.curMonth)),
    (day: number) => {
      GridItem() {
        // 日期内容
      }
    },
    (day: number) => `day_${day}`
  )
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr 1fr 1fr')

四、常见问题

4.1 日期对不齐

问题:日期数字与星期标题行不对齐。

原因 :getFirstDayOfMonth() 返回值与星期标题行不匹配。

解决方案 :确保星期标题行从星期日开始:['日','一','二','三','四','五','六']。


总结

本文通过"海风日记"的日历页,深入讲解了 Grid 构建月历的实现:

  1. 7 列模板 :'1fr 1fr 1fr 1fr 1fr 1fr 1fr'
  2. 日期计算:getDaysInMonth、getFirstDayOfMonth
  3. 占位算法:createPlaceholderArray
  4. 键值管理 :placeholder_${i} 和 day_${day}

下一篇文章将深入讲解 日期计算工具函数,敬请期待。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源:

相关推荐
学长毕设4 小时前
基于springboot的食品仓库管理系统
java·spring boot·后端
滴滴答答哒4 小时前
ASP.NET Core + FaceRecognitionDotNet 人脸识别实战:DI 单例、特征向量持久化与 1:N 比对
后端·asp.net
熊猫钓鱼>_>4 小时前
碰一碰无网近场文件快传与断点续传【鸿蒙心迹】
华为·交互·harmonyos·arkts·鸿蒙·openharmony·鸿蒙心迹
captain3767 小时前
MyBatis操作数据库(入门2)
java·数据库·spring boot·后端·spring·mybatis
IT_陈寒8 小时前
Java序列化踩坑记:对象循环引用让我加班两小时
前端·人工智能·后端
每天进步一点点km8 小时前
自用-牛客网-华为机试编程模拟题1-python
华为od·华为·面试
泡海椒8 小时前
05-雷达图多维画像-信用评级多维画像
后端
王中阳Go8 小时前
5.27 分钟干完后端和全部测试:一场三小时笔试的五个失分点,四个不在代码上
大数据·数据库·人工智能·后端·大语言模型
大哥43098 小时前
Modbus 的"字序":一个配错就变成天文数字,或者干脆变成 0
后端
岩钧8 小时前
New API 源码解析:一个生产级 AI 网关的架构与实现
后端