react+moment.js封装日历组件

react搭配moment.js封装

与原声js相比,封装逻辑会简单很多

下载moment,js依赖

npm install moment -S   # npm
yarn add moment -S      # yarn

index.js

import React, { Component } from "react";
import moment from "moment";
// 导入样式
import "./index.less";
// class式
class Datecom extends Component {
  constructor(props) {
    super(props);
    this.state = {
      week: ["日", "一", "二", "三", "四", "五", "六"], //渲染日历星期 头数据
      monthsDay: [],// 日历渲染数据
      onDate: moment().format("YYYY-MM"), //当前选择月数据,默认当前月
    };
  }

  // 进入页面调用构造日历方法
  componentDidMount() {
    this.getthisMdate(this.state.onDate); //传入当前时间(默认)
  }


  // 构造日历数据
  getthisMdate = async (date) => {
    // 声明构造日历数据的数组
    let dateList = [];
    // 拿到传入的参数的月份第一日
    let thisIndex = moment(`${date}-01`).day();
    // 声明
    let frist = moment(`${date}-01`)
      .add(-thisIndex, "d")
      .format("YYYY-MM-DD HH:mm:ss");
    let thisMonths = moment().format("MM");
    // 日历六行七列,循环42遍构造
    for (let i = 0; i < 42; i++) {
      dateList.push({
        day: moment(frist).add(i, "d").format("YYYY-MM-DD"),
        type:
          moment(frist).add(i, "d").format("MM") !== moment(date).format("MM")
            ? 3 // 3代表不是本月的日期
            : moment(frist).add(i, "d").day() === 6 ||
              moment(frist).add(i, "d").day() === 0
            ? 1 // 1为周六周天
            : moment(frist).add(i, "d").format("YYYY-MM-DD") ===
              moment().format("YYYY-MM-DD")
            ? 2 // 2为当天
            : 0, // 0为工作日
      });
    }
    await this.setState({
      monthsDay: dateList,
    });
  };

  // 上个月
  onPrev = async (date) => {
    await this.setState({
      onDate: moment(date).add(-1, "months").format("YYYY-MM"),
    });
    this.getthisMdate(this.state.onDate);
  };

  //下个月
  onNext = async (date) => {
    await this.setState({
      onDate: moment(date)
        .add(+1, "months")
        .format("YYYY-MM"),
    });
    this.getthisMdate(this.state.onDate);
  };

  render() {
    let { week, monthsDay, onDate } = this.state;
    return (
      <div className="datecom">
        <div className="topBtn">
          <p className="toup" onClick={() => this.onPrev(onDate)}>
            <svg
              t="1665712612567"
              class="icon"
              viewBox="0 0 1024 1024"
              version="1.1"
              xmlns="http://www.w3.org/2000/svg"
              p-id="1374"
              width="15"
              height="15"
            >
              <path
                d="M378.24 512l418.88 418.88L704 1024 192 512l512-512 93.12 93.12z"
                fill="#707070"
                p-id="1375"
              ></path>
            </svg>
          </p>
          <p className="dateText">{onDate}</p>
          <p className="tolow" onClick={() => this.onNext(onDate)}>
            <svg
              t="1665712653767"
              class="icon"
              viewBox="0 0 1024 1024"
              version="1.1"
              xmlns="http://www.w3.org/2000/svg"
              p-id="2335"
              width="15"
              height="15"
            >
              <path
                d="M610.88 512L192 93.12 285.12 0l512 512-512 512L192 930.88z"
                fill="#8a8a8a"
                p-id="2336"
              ></path>
            </svg>
          </p>
        </div>
        <div className="dateDiv">
          <div className="top">
            {week.map((el, index) => {
              return (
                <div
                  className={
                    index === 0 || index === 6 ? "weekedtop" : "daytop"
                  }
                >
                  {el}
                </div>
              );
            })}
          </div>
          <div className="row">
            {monthsDay.map((el, index) => {
              return (
                <div
                  className={
                    el.type === 1
                      ? "weekend"
                      : el.type === 0
                      ? "day"
                      : el.type === 2
                      ? "thisday"
                      : el.type === 3
                      ? "notMonths"
                      : ""
                  }
                >
                  {moment(el.day).format("DD")}
                </div>
              );
            })}
          </div>
        </div>
      </div>
    );
  }
}

export default Datecom;

index.less

.datecom {
  width: 70%;
  height: 70%;
  display: flex;
  flex-direction: column;
  margin-left: 5px;
  .topBtn {
    width: 100%;
    height: 40px;
    background: #fff;
    display: flex;
    justify-content: space-around;
    align-items: center;
    .toup,
    .tolow {
      width: 20px;
      height: 20px;
      // background: #eee;
      // border-radius: 50%;
      text-align: center;
      line-height: 20px;
      font-size: 12px;
      cursor: pointer;
      // margin-left: 30%;
    }
    .toup {
      margin-left: 40%;
    }
    .dateText {
      // margin-left: 50%;
    }
    .tolow {
      margin-right: 40%;
    }
  }
  .dateDiv {
    flex: 1;
    background: #fff;
    display: flex;
    flex-direction: column;
    .top {
      width: 100%;
      height: 30px;
      background: #fff;
      display: flex;
      justify-content: space-between;
      margin-bottom: 3px;
      .daytop {
        width: 14%;
        height: 100%;
        background: #ddd;
        text-align: center;
        line-height: 30px;
        border-radius: 5px;
      }
      .weekedtop {
        width: 14%;
        height: 100%;
        background: #ccc;
        text-align: center;
        line-height: 30px;
        border-radius: 5px;
      }
    }
    .row {
      width: 100%;
      height: auto;
      flex: 1;

      background: #fff;
      display: flex;
      justify-content: space-between;
      flex-wrap: wrap;
      .day {
        width: 14%;
        // height: 100%;
        background: #ddd;
        margin-bottom: 4px;
        border-radius: 5px;
      }
      .weekend {
        width: 14%;
        // height: 100%;
        background: #ccc;
        margin-bottom: 4px;
        border-radius: 5px;
      }
      .thisday {
        width: 14%;
        // height: 100%;
        background: rgb(173, 227, 248);
        margin-bottom: 4px;
        border-radius: 5px;
      }
      .notMonths {
        width: 14%;
        // height: 100%;
        background: #eee;
        margin-bottom: 4px;
        color: #ddd;
        border-radius: 5px;
      }
    }
  }
}

效果:当前只是demo,想要简洁修改一下css就好

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值