react使用Fullcalendar 实战用法

使用步骤请参考:react使用Fullcalendar

卡片式的日历:

需求图:
需求图
卡片式的日历,其实我是推荐 antd的,我两个都写了一下都能实现。

antd 的代码:

antd的我直接用的官网示例:antd 日历示例

import React, {
    
     useEffect, useState, useRef } from 'react';
import {
    
     Calendar, Col, Radio, Row, Select, Typography } from 'antd';
import "./index.less"
import moment from 'moment';
const ProductFullcalendar = () => {
    
    
    const [currentDate, setCurrentDate] = useState(moment()); //当前日期



    const onPanelChange = (value, mode) => {
    
    
        console.log(value.format('YYYY-MM-DD'), mode);
    };



    return (
        <div className='vv'>
            产品日历
            <Calendar
                fullscreen={
    
    false}
                onPanelChange={
    
    onPanelChange}
                dateFullCellRender={
    
    (current) => {
    
    
                    let currentDate1 = moment(current).format('YYYY-MM-DD');
                    let selectDate = currentDate.format('YYYY-MM-DD');
                    if (currentDate1 === selectDate) {
    
    
                        return <div className='dateCell selected'>
                            <div className='date_select'>{
    
    moment(current).format('DD')}</div>
                            <div className='event_select'></div>
                        </div>
                    } else {
    
    
                        return <div className='dateCell'>
                            <div className='date'>{
    
    moment(current).format('DD')}</div>

                        </div>
                    }
                }}
                onSelect={
    
    (date) => {
    
    
                    setCurrentDate(date);
                }}
            />

        </div>
    )
};
export default ProductFullcalendar;

less:

.vv {
    
    
    .ant-picker-cell {
    
    
        color: rgba(0, 0, 0, 0.3);
    }

    .ant-picker-cell-in-view {
    
    
        color: rgba(0, 0, 0, 0.87);
    }

    .selected {
    
    
        background: #3D57B1;
        box-shadow: 0px 2px 6px 0px rgba(33, 77, 208, 0.36);
        border-radius: 8px;

        .date_select {
    
    
            font-family: Avenir, Avenir;
            font-weight: 500;
            font-size: 20px;
            color: #FFFFFF;
        }
        .event_select{
    
    
            width: 6px;
            height: 6px;
            background: #FFFFFF;
            border-radius: 50%;
        }
    }

    .dateCell {
    
    
        width: 48px;
        height: 55px;
        border-radius: 8px;
        margin: 0 auto;
        display: flex;
        align-items: center;
        justify-content: center;
        flex-direction: column;

        .date {
    
    
            font-family: Avenir, Avenir;
            font-weight: 500;
            font-size: 20px;
        }
        .event{
    
    
            width: 6px;
            height: 6px;
            background: red;
            border-radius: 50%;
        }
    }
}

@fullcalendar/react的代码:

它需要处理的东西很多,点击上个月的日期时,需要自己跳到上一个月。

import React, {
    
     useEffect, useState, useRef } from 'react';
import FullCalendar from '@fullcalendar/react'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin from "@fullcalendar/interaction"
import "./index.less"
const ProductFullcalendar = () => {
    
    
    const [currentDate, setCurrentDate] = useState(); //当前日期
    // 创建一个 ref 来存储 FullCalendar 的实例  
    const calendarRef = useRef(null);
    const renderEventContent = (eventInfo) => {
    
    
        return <div className='kk'></div>
    }
    const events = [
        {
    
     title: '', start: new Date(2024, 10, 1) }
    ]
    const dayCellContent = (data) => {
    
    
        console.log(data, currentDate, "908777");
        let dayDate = data.dayNumberText.replace("日", "");
        let isToday = data.isToday;
        //是不是当月的日期
        let isOther = data.isOther;
        return <div className='dayCellContent'>
            <div className={
    
    'dayDate'}>{
    
    dayDate}</div>

        </div>
    }
    return (
        <div className='vv'>
            产品日历
            <FullCalendar
                ref={
    
    calendarRef}
                plugins={
    
    [dayGridPlugin, interactionPlugin]}
                initialView='dayGridMonth'
                events={
    
    events}
                eventContent={
    
    renderEventContent}
                dayCellClassNames={
    
    "dayCell"}
                locale='zh-cn'// 设置语言
                selectable={
    
    true}
                dateClick={
    
    (info) => {
    
    
                    document.querySelectorAll('.fc-day.selected').forEach(function (el) {
    
    
                        el.classList.remove('selected');
                    });
                    const clickedDate = info.date;
                    //console.log(calendarRef.current.getApi()?.getDate(),calendarRef,"987")
                    const currentViewDate = calendarRef?.current?.getApi()?.getDate(); // 获取当前视图的日期
                    // 判断是否为同一月份
                    if (clickedDate.getMonth() !== currentViewDate.getMonth() ||
                        clickedDate.getFullYear() !== currentViewDate.getFullYear()) {
    
    
                        // 如果不是当月日期,则切换到点击的月份
                        calendarRef?.current?.getApi()?.gotoDate(clickedDate);
                    }
                    // calendarRef?.current?.getApi()?.refetchEvents(); // 刷新事件
                    setTimeout(() => {
    
    
                        info.dayEl.classList.add('selected');
                    })
                }}
                dayHeaderClassNames={
    
    "dayHeader"}
                dayHeaderContent={
    
    (arg) => {
    
    
                    // 自定义星期内容
                    const days = ['日', '一', '二', '三', '四', '五', '六']; // 星期的中文表示
                    return days[arg.date.getDay()]; // 获取对应星期的中文名称
                }}
                dayCellContent={
    
    (data) => {
    
    
                    return dayCellContent;
                }}
            />


        </div>
    )
};
export default ProductFullcalendar;

less代码:

.vv {
    
    
    --fc-border-color: none;
    --fc-highlight-color: none;
    --fc-today-bg-color: none;
    //日历总高度 包括 toolBar 和日历内容
    --fc-daygrid-height: 390px;
    // 单元格内容宽度 我自定义的
    // 单元格内容宽度 我自定义的
    --fc-daygrid-day-frame-width: 48px;
    // 单元格内容高度 我自定义的
    --fc-daygrid-day-frame-height: 55px;

    .fc-media-screen {
    
    
        height: var(--fc-daygrid-height);
    }

    .fc-header-toolbar {
    
    
        margin-bottom: 12px;
    }

    a {
    
    
        color: initial;
    }

    .fc-daygrid-day-events {
    
    
        min-height: 0 !important;
    }

    .dayCell {
    
    
        --fc-border-color: none;
        width: var(--fc-daygrid-day-frame-width);

        .fc-daygrid-day-frame {
    
    
            width: var(--fc-daygrid-day-frame-width);
            height: var(--fc-daygrid-day-frame-height);
            border-radius: 8px;
            display: flex;
            align-items: center;
            justify-content: center;
            flex-direction: column;
            margin: 0 auto;
        }
    }

    .fc-theme-standard th {
    
    
        border-bottom: 1px solid #F0F0F0;
    }

}

.dayHeader {
    
    
    font-weight: 400;
    font-size: 14px;
    color: rgba(0, 0, 0, 0.54) !important;
    width: var(--fc-daygrid-day-frame-width);
}

.kk {
    
    
    width: 6px;
    height: 6px;
    background: #FF7D7D;
    border-radius: 50%;
}

.fc-day-other {
    
    
    color: rgba(0, 0, 0, 0.3);
}

.fc-daygrid-day {
    
    
    color: rgba(0, 0, 0, 0.87);
}

.dayCellContent {
    
    
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    line-height: 20px;

    .dayDate {
    
    
        font-family: Avenir, Avenir;
        font-weight: 800;
        font-size: 20px;
    }



    .dayEvent {
    
    
        margin-top: 2px;

        .dayEventItem {
    
    
            width: 6px;
            height: 6px;
            background: #4982F3;
            border-radius: 50%;
        }
    }

}


.selected {
    
    
    width: var(--fc-daygrid-day-frame-width);

    .fc-daygrid-day-frame {
    
    
        width: var(--fc-daygrid-day-frame-width);
        height: var(--fc-daygrid-day-frame-height);
        border-radius: 8px;
        display: flex;
        align-items: center;
        justify-content: center;
        flex-direction: column;
        margin: 0 auto;
        background: #3D57B1;
        box-shadow: 0px 2px 6px 0px rgba(33, 77, 208, 0.36);


        .fc-daygrid-day-events {
    
    
            .kk {
    
    
                width: 6px;
                height: 6px;
                background: #FFFFFF;
                border-radius: 50%;
            }
        }

        .dayCellContent {
    
    
            display: flex;
            align-items: center;
            justify-content: center;
            flex-direction: column;


            .dayDate {
    
    
                font-family: Avenir, Avenir;
                font-weight: 800;
                font-size: 20px;
                color: #FFFFFF;
            }

            .dayEvent {
    
    
                margin-top: 2px;
            }

        }
    }
}

antd官网代码:

import {
    
     Calendar, Col, Radio, Row, Select, Typography } from 'antd';
import React from 'react';
const App = () => {
    
    
  const onPanelChange = (value, mode) => {
    
    
    console.log(value.format('YYYY-MM-DD'), mode);
  };
  return (
    <div className="site-calendar-customize-header-wrapper">
      <Calendar
        fullscreen={
    
    false}
        headerRender={
    
    ({
     
      value, type, onChange, onTypeChange }) => {
    
    
          const start = 0;
          const end = 12;
          const monthOptions = [];
          const current = value.clone();
          const localeData = value.localeData();
          const months = [];
          for (let i = 0; i < 12; i++) {
    
    
            current.month(i);
            months.push(localeData.monthsShort(current));
          }
          for (let i = start; i < end; i++) {
    
    
            monthOptions.push(
              <Select.Option key={
    
    i} value={
    
    i} className="month-item">
                {
    
    months[i]}
              </Select.Option>,
            );
          }
          const year = value.year();
          const month = value.month();
          const options = [];
          for (let i = year - 10; i < year + 10; i += 1) {
    
    
            options.push(
              <Select.Option key={
    
    i} value={
    
    i} className="year-item">
                {
    
    i}
              </Select.Option>,
            );
          }
          return (
            <div
              style={
    
    {
    
    
                padding: 8,
              }}
            >
              <Typography.Title level={
    
    4}>Custom header</Typography.Title>
              <Row gutter={
    
    8}>
                <Col>
                  <Radio.Group
                    size="small"
                    onChange={
    
    (e) => onTypeChange(e.target.value)}
                    value={
    
    type}
                  >
                    <Radio.Button value="month">Month</Radio.Button>
                    <Radio.Button value="year">Year</Radio.Button>
                  </Radio.Group>
                </Col>
                <Col>
                  <Select
                    size="small"
                    dropdownMatchSelectWidth={
    
    false}
                    className="my-year-select"
                    value={
    
    year}
                    onChange={
    
    (newYear) => {
    
    
                      const now = value.clone().year(newYear);
                      onChange(now);
                    }}
                  >
                    {
    
    options}
                  </Select>
                </Col>
                <Col>
                  <Select
                    size="small"
                    dropdownMatchSelectWidth={
    
    false}
                    value={
    
    month}
                    onChange={
    
    (newMonth) => {
    
    
                      const now = value.clone().month(newMonth);
                      onChange(now);
                    }}
                  >
                    {
    
    monthOptions}
                  </Select>
                </Col>
              </Row>
            </div>
          );
        }}
        onPanelChange={
    
    onPanelChange}
      />
    </div>
  );
};
export default App;

正常日历 antd 和 Fullcalendar 都行:

我的需求是:
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/98d2aad49f5c407dae7b53d630ae7c7a.png
我直接用的@fullcalendar/react 因为我的和它基本功能完全一致。具体怎么选看自己。

官网的demo效果:
在这里插入图片描述
我的需求:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44058725/article/details/143436411