React FullCalendar 日历组件使用

700 阅读2分钟

FullCalendar 日历 支持多种框架,具体可以参考fullcalendar.io/docs/, 我的项目框架是react, 需要其月日历的功能(周日历功能也很强大),以 react 为例:

1. 首先 FullCalendar 的依赖都是按需引用的,如果是 react,则引用 react 相关的依赖即可

@fullcalendar/react @fullcalendar/daygrid 日历的基本样式依赖

@fullcalendar/interaction 日历事件的依赖

微信图片_20230721152058.png

2. FullCalendar的部分属性功能

  • ref 绑定日历后 你可以通过 ref 获取方法事件 比如:calendarRef.current.getApi().today()
  • timeZone: 时区设置 但是返回的还是浏览器时区 这个需要注意一下 暂时不清楚怎么让其默认返回所设置时区的时间
  • plugins: 用来添加依赖插件
  • initialView: 初始化指定的日历模式,默认为月日历
  • selectable: 格子可选中高亮
  • select: 选中格子的回调
  • headerToolbar: 日历头部 start/center/end 分别为左中右,默认值是{ start:'title' ,center:'', end:'today prev,next'}
  • customButtons: 自定义按钮,这里因为我需要监听上一页下一页的换页事件,因此我重写了左右切换页按钮
  • dayCellContent: 自定义日期格子中的样式内容
    <FullCalendar
        ref={calendarRef}
        timeZone={timeZone}
        plugins={[dayGridPlugin, interactionPlugin]}
        initialView="dayGridMonth"
        selectable
        select={dateSelect}
        headerToolbar={{
          start: 'title', // 日历月份
          center: '',
          end: 'customToDay,prevMonthCustom,nextMonthCustom'
        }}
        customButtons={{
          customToDay: {
            text: 'Today',
            click: () => {
              calendarRef.current.getApi().today()
            }
          },
          prevMonthCustom: {
            text: 'Previous',
            click: function () {
              calendarRef.current.getApi().prev()
              getMonthData()
            }
          },
          nextMonthCustom: {
            text: 'Next',
            click: function () {
              calendarRef.current.getApi().next()
              getMonthData()
            }
          }
        }}
        dayCellContent={handleDayCellContent}
      />

全部代码如下

import FullCalendar from '@fullcalendar/react'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin from '@fullcalendar/interaction'
import { getLocalUser } from 'src/services/config'
import { useEffect, useRef, useState } from 'react'
import { getScheduleSlotsPreview } from 'src/apis/schedule'
import './fullCalendar.scss'

const CalendarMonth = () => {
  const calendarRef = useRef(null)

  // 获取用户时区
  const timeZone = getLocalUser().timezone

  const [events, setEvents] = useState([])

  // 选中格子回调
  const dateSelect = info => {
    // console.log('info')
  }

  const handleDayCellContent = arg => {
    const date = arg.date.getDate()

    return (
      <div className='w-full'>
        {/* 日期 */}
        <div className='text-right'>{date}</div>

        {/* 这里可以根据服务返回的events数据自定义显示的样式 */}
        <div>自定义内容</div>
      </div>
    )
  }

  const getMonthActiveSlot = async () => {
    // 请求服务 获取本月需要操作的天数
    let { data } = await getScheduleSlotsPreview(query)

    setEvents(data)
  }

  // 切换月份获取课程信息
  const getMonthData = () => {
    const calendarApi = calendarRef.current.getApi()
    // 获取日历显示的第一天和最后一天 这里获取的是当前浏览器时区
    const startDate = calendarApi.view.activeStart
    const endDate = calendarApi.view.activeEnd

    // 请求服务
    getMonthActiveSlot({
      start_time: utcStartDate,
      end_time: utcEndDate
    })
  }

  useEffect(() => {
    getMonthData()
  }, [])

  return (
    <div className='w-[98%]'>
      <FullCalendar
        ref={calendarRef}
        timeZone={timeZone}
        plugins={[dayGridPlugin, interactionPlugin]}
        initialView='dayGridMonth'
        selectable
        select={dateSelect}
        headerToolbar={{
          start: 'title',
          center: '',
          end: 'customToDay,prevMonthCustom,nextMonthCustom'
        }}
        customButtons={{
          customToDay: {
            text: 'Today',
            click: () => {
              calendarRef.current.getApi().today()
            }
          },
          prevMonthCustom: {
            text: 'Previous',
            click: function () {
              calendarRef.current.getApi().prev()
              getMonthData()
            }
          },
          nextMonthCustom: {
            text: 'Next',
            click: function () {
              calendarRef.current.getApi().next()
              getMonthData()
            }
          }
        }}
        dayCellContent={handleDayCellContent}
      />
    </div>
  )
}

export default CalendarMonth