简单的日历组件
import React, { Component } from "react";import * as _ from "lodash";const l = console.log;const weeks = ["日", "一", "二", "三", "四", "五", "六"];class Test extends Component { state = {}; componentWillMount() { this.initState(); } initState = ({ y, m } = {}) => { let date = new Date(); let year = y || date.getFullYear(); // 本年 let month = m || date.getMonth() + 1; // 本月 l(`${year}年${month}月.`); let date2 = new Date(year, month, 0); let days = date2.getDate(); // 本月有多少天 l(`本月有${days}天.`); date2.setDate(1); let day = date2.getDay(); // 本月第一天是星期几 l(`本月第一天是星期${day}.`); let list = []; for (let i = 0; i < days + day; i++) { if (i < day) { list.push(0); } else { list.push(i - day + 1); } } let hlist = _.chunk(list, 7); // 转化为二维数组 let len = hlist.length; let to = 7 - hlist[len - 1].length; // 循环尾部补空格 for (let i = 0; i < to; i++) { hlist[len - 1].push(0); } this.setState({ date, year, month, days, day, hlist, }); }; // 上月 handlePrevMonth = () => { let prevMonth = this.state.month + -1; let prevYear = this.state.year; if (prevMonth < 1) { prevMonth = 12; prevYear -= 1; } this.initState({ y: prevYear, m: prevMonth, }); }; // 下月 handleNextMonth = () => { let nextMonth = this.state.month + 1; let nextYear = this.state.year; if (nextMonth > 12) { nextMonth = 1; nextYear += 1; } this.initState({ y: nextYear, m: nextMonth, }); }; render() { const { year, month } = this.state; return ( <>{year}年,{month}月
{el} | ))}
---|
{n} | ))}
2
import React, { Component } from "react";import * as _ from "lodash";class DateItem { /** * * @param dayNum 日数, 如果和 new Date().getDate() 相等则是今天 * @param isSignIn=false 是否签到 * @param isShowSignIn=false 是否显示是否签到,大于今日和这个月的日期应该都不显示 */ constructor({ dayNum, isSignIn = false, isShowSignIn = false }) { Object.assign(this, { dayNum, isSignIn, isShowSignIn, }); }}const l = console.log;const weeks = ["日", "一", "二", "三", "四", "五", "六"];class Test extends Component { state = {}; componentWillMount() { this.initState(); } initState = ({ y, m } = {}) => { const date = new Date(); const year = y || date.getFullYear(); // 本年 const month = m || date.getMonth() + 1; // 本月 l(`${year}年${month}月.`); let date2 = new Date(year, month, 0); let days = date2.getDate(); // 本月有多少天 l(`本月有${days}天.`); date2.setDate(1); let day = date2.getDay(); // 本月第一天是星期几 l(`本月第一天是星期${day}.`); let list = []; const nowadays = date.getDate(); // 本日 const thisMonth = date.getMonth() + 1; // 本月 let isShowSignIn = false; const date2GtDate = date2 > date; const isThisMonth = month === thisMonth; // 选择的日期的月份是否是本月 for (let i = 0; i < days + day; i++) { const dayNum = i - day + 1; if (date2GtDate) { isShowSignIn = false; } else { if (isThisMonth && i >= day + nowadays) { isShowSignIn = false; } else { isShowSignIn = true; } } if (i < day) { list.push(new DateItem({ dayNum: 0, isShowSignIn })); } else { list.push(new DateItem({ dayNum, isShowSignIn })); } } let hlist = this.getHlist(list, isShowSignIn); this.setState({ date, year, month, days, day, list, hlist, nowadays, thisMonth, }); }; // 把一维日期切成二维日期 getHlist = (list, isShowSignIn) => { let hlist = _.chunk(list, 7); // 转化为二维数组 let len = hlist.length; let to = 7 - hlist[len - 1].length; // 循环尾部补空格 for (let i = 0; i < to; i++) { hlist[len - 1].push(new DateItem({ dayNum: 0, isShowSignIn })); } return hlist; }; // 上月 handlePrevMonth = () => { let prevMonth = this.state.month + -1; let prevYear = this.state.year; if (prevMonth < 1) { prevMonth = 12; prevYear -= 1; } this.initState({ y: prevYear, m: prevMonth, }); }; // 下月 handleNextMonth = () => { let nextMonth = this.state.month + 1; let nextYear = this.state.year; if (nextMonth > 12) { nextMonth = 1; nextYear += 1; } this.initState({ y: nextYear, m: nextMonth, }); }; // 点击每个日期 handleDateItemClick = (dateItem, i, j) => () => { const { year, month, date, nowadays } = this.state; const { isShowSignIn, isSignIn, dayNum } = dateItem; if (dayNum === 0) return; const selectDate = new Date(`${year}-${month}-${dayNum}`); if (nowadays === dayNum) { l("签到"); } else if (selectDate < date) { l("补签"); } if (!isShowSignIn || isSignIn) // 不能签到的日期和已签到的日期直接返回 return; this.setState(state => { const hlist = state.hlist.slice(); hlist[i][j].isSignIn = true; return { hlist, }; }); }; render() { const { year, month, nowadays, thisMonth } = this.state; return ( <>{year}年,{month}月
{el} | ))}
---|
{dayNum} {!!isShowSignIn && ( {!!isSignIn ? `已签到` : `未签到`} )} | ); })}