react中基于moment库实现日历组件

效果图:
在这里插入图片描述

import React, { Component } from 'react'
import moment from 'moment'
import y, { cm } from '../until/style'

const week = ['日', '一', '二', '三', '四', '五', '六']


class Calendar extends Component {
    constructor(props) {
        super(props)
        const { defaultVlue } = this.props
        this.state = {
            curMonth: defaultVlue ? moment(defaultVlue) : moment(),//当前月
            activeDay: defaultVlue ? moment(defaultVlue) : moment()//选中日期
        }
    }
    /** 
     * 上月数据 
     * 思路:首先要知道当前月的1号是星期几,这样才能知道要渲染多少个上个月的日子
     */

    lastMonth() {
        const date = moment(this.state.curMonth).date(1);// 当前月的1号
        const count = date.day();//1号是星期几
        date.subtract(count, "day");//比如本月1号是星期3,那么上个月的数据就应该显示3个
        let ui = []
        for (let i = 0; i < count; i++) {
            ui.push(
                <div key={'lastMonth_' + i} style={cm(y.color('#999'), y.h(50), y.wRatio(100 / 7), y.ujc, y.uac)}>{date.date()}</div>
            )
            date.add(1, 'day')
        }
        return ui
    }

    /**  
     * 下月数据 
     * 思路:首先获取本月1号的日期信息,然后通过add方法加1个月,就得到了下月1号的信息,从而得到下月1号是星期几,如果下月数据是星期2,那么下月数据就应该渲染7-2个
     * moment.js 中day()方法,如果是星期日,返回值为0
     */
    nextMonth() {
        //选中的时间改为1号,并且加上1个月
        const date = moment(this.state.curMonth).date(1).add(1, "months");
        const count = 7 - date.day();//7-星期几,就可知道要渲染几个下月数据
        if (count === 7) {
            return null;
        }
        let ui = []
        for (let i = 0; i < count; i++) {
            ui.push(
                <div
                    style={cm(y.wRatio(100 / 7), y.color('#999'), y.h(50), y.ujc, y.uac)} key={'nextMonth_' + i}>{date.date()}</div>
            )
            date.add(1, 'day')
        }
        return ui
    }

    /**  
     * 本月数据 
     * 思路:通过moment.js 的daysInMonth方法获取当月天数
     */

    thisMonth() {
        const date = moment(this.state.curMonth).date(1);//获取本月1号数据
        const count = date.daysInMonth();//当前选中月份的总条数
        //最后一个工作日,本月1号,+1月-1天=本月最后一天
        let ui = []
        for (let i = 0; i < count; i++) {
            const todayMoment = moment(date);
            const isSame = this.state.activeDay && todayMoment.isSame(this.state.activeDay, "day");//判断哪一天是选中日期
            ui.push(
                <div
                    key={'thisMonth_' + i}
                    style={cm(y.wRatio(100 / 7), y.ujc)}>
                    <div
                        style={cm(y.h(50), y.w(50), y.radiusA(25), y.ujc, y.uac, y.bgColor(isSame ? "blue" : "#fff"), y.color(isSame ? "#fff" : "#333"))}
                        onClick={() => {
                            this.setState({
                                activeDay: todayMoment
                            });
                            this.props.onPressDay && this.props.onPressDay(todayMoment);
                        }}
                    >{date.date()}</div>
                </div>
            )
            date.add(1, "day");
        }
        return ui
    }



    render() {
        return (
            <div style={cm(y.bgColor('#fff'), y.udc, y.cursor('pointer'))}>
                {/* 控制按钮 */}
                <div style={cm(y.udr, y.uac, y.uja, y.mtb(12))}>
                    <button onClick={() => {
                        this.setState({
                            curMonth: this.state.curMonth.subtract(1, 'year')
                        })
                    }}>去年子</button>
                    <button onClick={() => {
                        this.setState({
                            curMonth: this.state.curMonth.subtract(1, 'month')
                        })
                    }}>上月</button>
                    <h3>{this.state.curMonth.format('YYYY-MM')}</h3>
                    <button onClick={() => {
                        this.setState({
                            curMonth: this.state.curMonth.add(1, 'month')
                        })
                    }}>下月</button>
                    <button onClick={() => {
                        this.setState({
                            curMonth: this.state.curMonth.add(1, 'year')
                        })
                    }}>明年子</button>
                </div>
                {/* 星期 */}
                <div style={cm(y.udr, y.uac)}>
                    {week.map((item, index) => {
                        return (
                            <div key={'week_' + index} style={cm(y.wRatio(100 / 7), y.ujc)}>{item}</div>
                        )
                    })}
                </div>
                <div style={cm(y.udr, y.uac, y.uWrap)}>
                    {this.lastMonth()}
                    {this.thisMonth()}
                    {this.nextMonth()}
                </div>
            </div>
        )
    }
}

export default Calendar


使用:

 <Calendar
        defaultVlue={'2021-01-02'}
        onPressDay={(date) => {}}/>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值