Fullcalendar插件的使用

设计需求

因为设计稿是这样的

设计稿
像日历又不完全是日历,所以本来想用antd的日历组件也用不了

在这里插入图片描述

还好Fullcalendar插件可以满足

安装

npm install --save @fullcalendar/react @fullcalendar/daygrid @fullcalendar/timegrid @fullcalendar/interaction

不说太多上代码

具体看注释

import React, { useState, useRef, useMemo } from 'react';
import { Space, Row, Divider, message } from 'antd';
import FullCalendar from '@fullcalendar/react'; // must go before plugins
import dayGridPlugin from '@fullcalendar/daygrid'; // a plugin!
import timeGridPlugin from '@fullcalendar/timegrid';
import interactionPlugin from '@fullcalendar/interaction'; // needed for dayClick
import dayjs from 'dayjs';
import moment from 'moment';
import { uniqueId } from 'lodash';
import '@fullcalendar/daygrid/main.css';
import '@fullcalendar/timegrid/main.css';
import '../styles/dialTimeRange.scss';


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

// 拨打时间范围弹窗
const DialTimeRange = ({ timeList = [], ...props }) => {
 const [ eventList, setEventList ] = useState(useMemo(() => timeList, [timeList]));
 const calendarComponentRef = useRef();


 // render header
 // 每列的头部渲染
 const columnHeaderHtml = (date) => {
  const day = dayjs(date.date).day(); // 获取周几
  return <span>{week[day]}</span>;
 };

 // 判断时间是否重复
 const getRepeatDates = (start, end, eventsList) => {
  let repeats =
   eventsList &&
   eventsList.filter((x) => {
    return (
     (x.start < start && x.end > start) ||
     (x.start > start && x.end <= end) ||
     (x.start < end && x.end >= end)
    );
   });
  return repeats;
 };

 const weekList = () => {
  const weekTimeList = [ {} ];
  for (let i = 0; i < 7; i++) {
   weekTimeList.push({
    start: dayjs(`2021-08-${16 + i} 09:00:00`).format(),
    end: dayjs(`2021-08-${16 + i}  20:00:00`).format()
   });
  }
  return weekTimeList;
 };

 // 将跨天的事件转化成单天的事件
 const handleTransformEventList = (eStart, eEnd, startWeek, endWeek) => {
  const weeklist = weekList();

  // 开始时间不是09:00
  eventList.push({
   ...weeklist[startWeek],
   start: eStart,
   id: uniqueId(),
   weekRange: startWeek,
   startTimeStr: dayjs(eStart).format('HH:mm'),
   endTimeStr: dayjs(weeklist[startWeek]['end']).format('HH:mm')
  });

  if (endWeek - startWeek >= 2) {
   // 比如框选了周一某点到周三某点
   // 这是中间肯定被选了整天,所以用09:00~20:00 即可
   for (let i = startWeek + 1; i <= endWeek - startWeek; i++) {
    eventList.push({
     ...weeklist[i],
     id: uniqueId(),
     weekRange: i,
     startTimeStr: dayjs(weeklist[startWeek]['start']).format('HH:mm'),
     endTimeStr: dayjs(weeklist[startWeek]['end']).format('HH:mm')
    });
   }
  }
  // 结束时间不是20:00
  eventList.push({
   ...weeklist[endWeek],
   end: eEnd,
   id: uniqueId(),
   weekRange: endWeek,
   startTimeStr: dayjs(weeklist[startWeek]['start']).format('HH:mm'),
   endTimeStr: dayjs(eEnd).format('HH:mm')
  });

  return eventList;
 };

 // 选择
 const handleSelect = (event) => {
  const eStart = event.start;
  const eEnd = event.end;
  // 校验时间是否重叠
  let repeats = getRepeatDates(eStart, eEnd, eventList);
  if (repeats.length > 0) {
   calendarComponentRef.current._calendarApi.unselect(); // 清除选择的重复时间段
   message.error('选择的时间段中已存在重复时间段');
   return;
  }

  const startWeek = dayjs(eStart).day();
  const endWeek = dayjs(eEnd).day() || 7; // 后面都是把7当做周日,而不是0

  if (startWeek === endWeek) {
   // 说明选的是同一天的
   eventList.push({
    id: uniqueId(),
    start: eStart,
    end: eEnd,
    weekRange: startWeek,
    startWeek,
    endWeek,
    startTimeStr: dayjs(eStart).format('HH:mm'),
    endTimeStr: dayjs(eEnd).format('HH:mm')
    // display: 'background', // 添加了这个就不能获取事件点击事件
    // color: '#466DFF'
   });
  } else {
   // 跨天了
   handleTransformEventList(eStart, eEnd, startWeek, endWeek);
  }
  // }
  // console.log('handleSelect', eventList);
  setEventList([...eventList]);
 };
 // 事件点击
 const handleventClick = (arg) => {
  let id = arg.event.id;
  // let data = arg.event.extendedProps; // 可以查看自定义数据
  const idIndex = eventList.findIndex((ev) => ev.id === id);
  eventList.splice(idIndex, 1); //删除已选择的事件
  setEventList([ ...eventList ]);

  // console.log('handleventClick', arg)
 };


 const handleUnSelect = (event) => {
  console.log({ event });
 };
 // console.log({ eventList, setEventList });
 return (
   <FullCalendar
    ref={calendarComponentRef}
    plugins={[ dayGridPlugin, timeGridPlugin, interactionPlugin ]}
    initialView="timeGridWeek" // 默认为哪个视图(月:dayGridMonth,周:timeGridWeek,日:timeGridDay)
    locale="zh-cn"
    firstDay={1} // 设置周一为第一天
    headerToolbar={false} // 设置日历头部按钮
    // editable={true}
    slotLabelFormat={{
     hour: '2-digit',
     minute: '2-digit',
     meridiem: true,
     hour12: false // 设置时间为24小时
    }}
    initialDate={moment('2021-08-16').format('YYYY-MM-DD')} // 自定义设置背景颜色时一定要初始化日期时间
    selectable={true} // 是否可选择
    allDaySlot={false} // 周,日视图时,all-day 不显示
    aspectRatio={1.6} // 设置日历单元格宽度与高度的比例。
    select={handleSelect} // 选中日历格事件
    unselect={handleUnSelect} // 不选触发的事件
    eventClick={handleventClick} // 点击日历日程事件
    events={eventList} // 事件数据
    dayHeaderContent={columnHeaderHtml} // 每天的头部内容
    slotMinTime="09:00:00" // 左边的时间最小从几点展示
    slotMaxTime="20:00:00" // 左边的时间最大展示到几点
    // eventContent={eventRender} // 时间的内容渲染
   />
 );
};

export default DialTimeRange;

官网传送门

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FullCalendar 是一个非常流行的日历插件,可以用来显示日程安排、事件等。它支持各种不同的视图(月视图、周视图、日视图等),并且可以自定义事件的颜色、标签等。 使用 FullCalendar 插件,你需要先在页面中引入 FullCalendarJavaScript 和 CSS 文件。然后,你需要在页面中创建一个空的 `div` 元素,并给它一个唯一的 ID。接下来,你可以在 JavaScript 中初始化 FullCalendar,并指定要显示的数据源(比如一个 JSON 数据文件或一个 AJAX 调用)。 以下是一个简单的 FullCalendar 示例代码: HTML 代码: ```html <!DOCTYPE html> <html> <head> <meta charset='utf-8' /> <link href='https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.10.2/fullcalendar.min.css' rel='stylesheet' /> <link href='https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.10.2/fullcalendar.print.min.css' rel='stylesheet' media='print' /> <script src='https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js'></script> <script src='https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.10.2/fullcalendar.min.js'></script> </head> <body> <div id='calendar'></div> <script> $(document).ready(function() { // page is now ready, initialize the calendar... $('#calendar').fullCalendar({ // put your options and callbacks here }) }); </script> </body> </html> ``` JavaScript 代码: ```javascript $('#calendar').fullCalendar({ events: [ { title: 'My Event', start: '2021-09-01' } ] }); ``` 这个例子中,我们首先在 HTML 中引入了 FullCalendarJavaScript 和 CSS 文件。然后,我们在页面中创建了一个空的 `div` 元素,并给它一个唯一的 ID(这里是 `calendar`)。接下来,在 JavaScript 中,我们使用 jQuery 的 `$(document).ready()` 方法来确保页面已经加载完毕后再初始化 FullCalendar。最后,我们指定了一个事件数据源,这个数据源只包含一个事件,它的标题是 `My Event`,开始时间是 2021 年 9 月 1 日。 当你打开这个页面时,你应该能看到一个简单的日历,上面显示着一个事件。你可以尝试添加更多的事件,或者尝试使用 FullCalendar 的其他功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值