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 都行:

我的需求是:
在这里插入图片描述
我直接用的@fullcalendar/react 因为我的和它基本功能完全一致。具体怎么选看自己。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/906587.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于SpringBoot+Vue实现智能停车收费系统

作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验&#xff0c;被多个学校常年聘为校外企业导师&#xff0c;指导学生毕业设计并参与学生毕业答辩指导&#xff0c;…

ApsaraMQ Serverless 能力再升级,事件驱动架构赋能 AI 应用

本文整理于 2024 年云栖大会阿里云智能集团高级技术专家金吉祥&#xff08;牟羽&#xff09;带来的主题演讲《ApsaraMQ Serverless 能力再升级&#xff0c;事件驱动架构赋能 AI 应用》 云消息队列 ApsaraMQ 全系列产品 Serverless 化&#xff0c;支持按量付费、自适应弹性、跨可…

基于SpringBoot+Vue实现高校毕业与学位资格审查系统

作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验&#xff0c;被多个学校常年聘为校外企业导师&#xff0c;指导学生毕业设计并参与学生毕业答辩指导&#xff0c;…

0.STM32F1移植到F0的各种经验总结

1.结构体的声明需放在函数的最前面 源代码&#xff1a; /*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //开启USART1的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructu…

RDT——清华开源的双臂机器人扩散大模型:先预训练后微调,支持语言、图像、动作多种输入

第一部分 清华开源全球最大双臂机器人扩散大模型RDT 2.1 什么是RDT 2.1.1 RDT推出的背景及其与以前工作的对比 受到最近在单手操作方面尝试的启发&#xff08;Brohan等&#xff0c;2023&#xff1b;Kim等&#xff0c;2024&#xff09;&#xff0c;清华一研究团队推出了RDT&a…

C++基础三(构造函数,形参默认值,函数重载,单例模式,析构函数,内联函数,拷贝构造函数)

C有六个默认函数&#xff0c;分别是&#xff1a; 1、默认构造函数; 2、默认拷贝构造函数; 3、默认析构函数; 4、赋值运算符; 5、取址运算符; 6、取址运算符const; 构造函数 构造函数(初始化类成员变量)&#xff1a; 1、属于类的成员函数之一 …

「DSA」C++排序算法 之 选择排序_Selection Sort_O(n²)

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「C/C」C/C程序设计&#x1f4da;全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…

完美洗牌的秘密(十三)——(反)完美洗牌第二定理的应用(16张的Anti faro周期魔术)...

早点关注我&#xff0c;精彩不错过&#xff01; 在前面的文章中&#xff0c;我们介绍了&#xff08;反&#xff09;完美洗牌定理的应用的海量魔术&#xff0c;详情请戳&#xff1a; 完美洗牌的秘密&#xff08;十二&#xff09;——反完美洗牌定理的应用扩展&#xff08;三叠发…

TOEIC 词汇专题:旅游计划篇

TOEIC 词汇专题&#xff1a;旅游计划篇 制定旅行计划时&#xff0c;尤其是跨国旅游&#xff0c;会涉及到很多独特的英语词汇。以下是与“旅游计划”相关的托业词汇&#xff0c;帮助你更加自如地规划行程。 1. 旅行服务和优惠 出发前了解一下与服务和优惠相关的常用词汇&#…

PVE定时开启关闭虚拟机,实现PVE中群晖虚拟机的定时开机和关闭

如果在PVE中安装了群晖&#xff0c;又不想每天关闭PVE(不在家&#xff0c;怕服务器起不来)&#xff0c;因此想每天定时关闭开启黑群晖和其他虚拟机释放资源。 在网上查了很多&#xff0c;说在crontab添加命令 00 2 * * * pvesh create /nodes/pve/qemu/102/status/stop 00 6 …

JDBC/ODBC—数据库连接API概述

JDBC/ODBC概述 在数据库连接领域&#xff0c;有两种广泛使用的技术&#xff1a;ODBC&#xff08;Open Database Connectivity - 开放数据库连接&#xff09;和 JDBC&#xff08;Java Database Connectivity - Java 数据库连接&#xff09;。 一、什么是 ODBC&#xff1f; Ope…

2024年NSSCTF秋季招新赛-WEB

The Beginning F12看源码&#xff0c;有flag http标头 黑吗喽 题目说要在发售时的0点0分&#xff0c;所以添加标头data Date: Tue, 20 Aug 2024 00:00:00 GMT然后改浏览器头 User-Agent: BlackMonkey曲奇就是Cookie cookieBlackMonkey这个一般就是Referer Referer:wukon…

后台管理系统的通用权限解决方案(十一)SpringBoot的统一异常处理

文章目录 1 统一异常处理介绍2 统一异常处理案例 1 统一异常处理介绍 在实际项目中&#xff0c;不可避免需要处理各种异常。如果每个都单独处理&#xff0c;代码中则会出现大量的try {...} catch {...} finally {...}代码块&#xff0c;不仅有大量的冗余代码&#xff0c;而且还…

Axure使用动态面板制作新闻栏目高级交互

亲爱的小伙伴&#xff0c;在您浏览之前&#xff0c;烦请关注一下&#xff0c;在此深表感谢&#xff01; 课程主题&#xff1a;使用动态面板制作新闻栏目 主要内容&#xff1a;动态面板State切换、控制&#xff1b;动态面板滚动设置&#xff1b;设置选中 应用场景&#xff1a…

android数组控件Textview

说明&#xff1a;android循环控件&#xff0c;注册和显示内容 效果图&#xff1a; step1: E:\projectgood\resget\demozz\IosDialogDemo-main\app\src\main\java\com\example\iosdialogdemo\TimerActivity.java package com.example.iosdialogdemo;import android.os.Bundl…

2024年10月文章一览

2024年10月编程人总共更新了21篇文章&#xff1a; 1.2024年9月文章一览 2.《Programming from the Ground Up》阅读笔记&#xff1a;p147-p180 3.《Programming from the Ground Up》阅读笔记&#xff1a;p181-p216 4.《Programming from the Ground Up》阅读笔记&#xff…

List 列表基础用法

List 列表基础用法 列表可以完成大多数集合类的数据结构实现。列表中元素的类型可以不相同&#xff0c;它支持数字&#xff0c;字符串甚至可以包含列表&#xff08;所谓嵌套&#xff09;。 列表是写在方括号 [] 之间、用逗号分隔开的元素列表。 和字符串一样&#xff0c;列表…

企业如何通过架构蓝图实现数字化转型

数字化转型的关键——架构蓝图的力量 在当今的商业世界&#xff0c;数字化转型已经不再是一个选择&#xff0c;而是企业生存与发展不可回避的战略行动。企业希望通过数字化提高效率、增强灵活性&#xff0c;并为客户提供更好的体验。然而&#xff0c;数字化转型不仅仅涉及技术…

数字马力二面面试总结

24.03.07数字马力二面面试总结 前段时间找工作,做的一些面试笔记总结 大家有面试录音或者记录的也可以发给我,我来整理答案呀 数字马力二面面试总结 24.03.07数字马力二面面试总结你可以挑一个你的最有挑战性的,有难度的,最具有复杂性的项目,可以简单说一下。有没有和算…

了解SQLExpress数据库

SQLExpress&#xff08;Microsoft SQL Server Express&#xff09;是由微软公司开发的一款免费且轻量级的数据库管理系统。以下是关于SQLExpress的详细解释&#xff1a; 一、定义与特点 定义&#xff1a; SQLExpress是Microsoft SQL Server的一个缩减版或基础版&#xff0c;旨在…