react 编写日历组件

原文链接: http://www.cnblogs.com/ajanuw/p/10100320.html

简单的日历组件

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}月

{weeks.map(el => ( ))} {this.state.hlist.map((el, i) => { return ( {el.map((n, ii) => ( ))} ); })}
{el}
{n}
); } } export default Test;

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}月

{weeks.map(el => ( ))} {this.state.hlist.map((el, i) => { return ( {el.map((dateItem, j) => { const dayNum = dateItem.dayNum; const isSignIn = dateItem.isSignIn; const isShowSignIn = dateItem.isShowSignIn; return ( ); })} ); })}
{el}
{dayNum}
{!!isShowSignIn && (
{!!isSignIn ? `已签到` : `未签到`}
)}
); } } export default Test;

转载于:https://www.cnblogs.com/ajanuw/p/10100320.html

你可能感兴趣的:(react 编写日历组件)