• react 编写日历组件


    简单的日历组件

    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 (
          <>
            <h2>
              {year}年,{month}月
            </h2>
            <div>
              <button onClick={this.handlePrevMonth}>上月</button>
              <button onClick={this.handleNextMonth}>下月</button>
            </div>
            <table>
              <tbody>
                <tr>
                  {weeks.map(el => (
                    <th key={el}>{el}</th>
                  ))}
                </tr>
                {this.state.hlist.map((el, i) => {
                  return (
                    <tr key={i}>
                      {el.map((n, ii) => (
                        <td key={ii}>{n}</td>
                      ))}
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </>
        );
      }
    }
    
    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 (
          <>
            <h2>
              {year}年,{month}月
            </h2>
            <div>
              <button onClick={this.handlePrevMonth}>上月</button>
              <button onClick={this.handleNextMonth}>下月</button>
              <button
                onClick={() => {
                  this.initState();
                }}
              >
                今天
              </button>
            </div>
            <table>
              <tbody>
                <tr>
                  {weeks.map(el => (
                    <th key={el}>{el}</th>
                  ))}
                </tr>
                {this.state.hlist.map((el, i) => {
                  return (
                    <tr key={i}>
                      {el.map((dateItem, j) => {
                        const dayNum = dateItem.dayNum;
                        const isSignIn = dateItem.isSignIn;
                        const isShowSignIn = dateItem.isShowSignIn;
                        return (
                          <td
                            key={j}
                            style={{
                              color:
                                dayNum === nowadays && month === thisMonth && "red",
                              textAlign: "center",
                              padding: 8,
    
                              border: "1px solid",
                              borderColor: dateItem.isSignIn
                                ? "red"
                                : "transparent",
                              opacity: dayNum === 0 ? 0 : 1,
                            }}
                            onClick={this.handleDateItemClick(dateItem, i, j)}
                          >
                            <div>{dayNum}</div>
                            {!!isShowSignIn && (
                              <div
                                style={{
                                  whiteSpace: "nowrap",
                                  fontSize: "12px",
                                }}
                              >
                                {!!isSignIn ? `已签到` : `未签到`}
                              </div>
                            )}
                          </td>
                        );
                      })}
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </>
        );
      }
    }
    
    export default Test;
    
  • 相关阅读:
    cnn softmax regression bp求导
    使用kd-tree加速k-means
    KDTree详解及java实现
    加入商品分类信息,考虑用户所处阶段的 图模型 推荐算法 Rws(random walk with stage)
    用户标签
    LDA(latent dirichlet allocation)
    对物品进行反馈 代码
    1.虚拟机中安装ubuntu
    4.动态HTML处理和机器图像识别
    3.非结构化数据与结构化数据提取
  • 原文地址:https://www.cnblogs.com/ajanuw/p/10100320.html
Copyright © 2020-2023  润新知