之前项目中有用到日历控件,当时由于时间问题,是在网上找到一个demo,然后二次开发的,从那时就想着自己写一个日历控件。这篇文章说明日历数据的处理,去除月份天数判断以及是否闰年判断。
设计(以最常用的按月份的日历)
日历其实大家都很熟悉,一切的设计都是从功能出发,这是根本。日历的功能分为两大块。
日历头部:当前年份/月份。
日历主体:当前月份的具体的日期信息。
日历主体的行数:现在我们看到的日历基本上为6行,因为一个月最多为31天,假设当前月的第一天为上一月最后一周的最后一天。如果是五行数据的话则只显示了29天,这也是为什么显示6行数据的原因。
功能点
日历初始渲染日期为当前月份
头部的左右滑动,日历数据需要显示对应月份的信息
点击日期本身可以进行相关数据操作,并且记录操作内容
可以根据调用这设置日历的每周数据以星期*为开始,星期天或者星期一。
首先思考日历的核心问题
如何获取当前日期的年份以及月份
/**
* 获取日历header内容 格式为:****年 **月
* @param {*} date
*/
export const getHeaderContent = function (date) {
let _date = new Date(date) return dateFormat(_date, 'yyyy年 MM月')
}
如何获取当前月份需要显示的42条数据(6*7),这42条数据是什么呢?
这个问题的核心是:当前月份显示的42条数据的第一天是哪一天?
这个问题的解决思路还要从上面的设计说起,上面提到日历主题的行数时,说到“假设当前月的第一天为上一月最后一周的最后一天”,那么42条数据显示的内容的第一条数据还要根据当前月的第一天是第一天所在周的第几天。
举例:2019-02-01
2月的第一天,星期五,所以当前月日历的第一天为2019-02-01 – 5
var date = new Date()
date.setDate(date.getDate() - date.getDay() + 1) // 获取当前月的第一天为2019-01-28这里有一问题是什么呢?
date.getDate()的值为0 – 6(0为周日,如果你的日历也是将周日放在日历的第一天,没什么问题,可是在中国是将周日放在最后一天的),这也就意味着前面的实现还需要考虑日历的放置顺序,因为日历是按照普通的周一到周日,还是周日到周一,我们获取的当月日历的第一天是不同的。所以上面的代码还要依赖于日历的排放顺序。
这里的排放顺序将是日历组件的第一个可被调用者控制的参数。这里我的设想是将该参数的传入值与date.getDay()匹配。










