react dva项目日历插件FullCalendar(v5)的使用

一、下载依赖

  cnpm i @fullcalendar/daygrid @fullcalendar/react @fullcalendar/timegrid

 

二、基本使用

  Calendar/index.tsx

import React, { useEffect, useState, useRef } from 'react'
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import { Drawer, Button, Form, Input, Select, DatePicker } from 'antd'
import { connect } from 'umi'
import FullCalendar from '@fullcalendar/react'
import dayGridPlugin from '@fullcalendar/daygrid'
import timeGridPlugin from '@fullcalendar/timegrid'
import { matchList } from './data'
import styles from './index.less'

interface props {}

const Calendar: React.FC<props> = () => {
  useEffect(() => {}, [])

  matchList &&
    matchList.forEach((item: any) => {
      item.borderColor = item.type === 1 ? '#62D78E' : '#416EFF'
    })

  const eventClick = (eventInfo: any) => {
    console.log(eventInfo)
    console.log(eventInfo.event._def)
  }

  return (
    <PageHeaderWrapper>
      <div className={styles.main}>
        <Button type="primary" className="add" onClick={handleAddOpen}>
          +新建日程
        </Button>
        <FullCalendar
          height={document.documentElement.offset - 150}
          // aspectRatio={2} // 宽度为高度的2倍
          initialView="timeGridWeek" // 初始化在week维度
          plugins={[dayGridPlugin, timeGridPlugin]}
          headerToolbar={{ left: '', center: 'prev,title,next today', right: '' }}
          locale="zh-cn"
          buttonText={{ today: '今天', month: '月', week: '周', day: '天' }}
          allDaySlot={false} // 不显示all-day
          firstDay={6} // 从周六开始
          scrollTime={'06:00:00'} // 初始滚动条滚动到的时间位置:6点
          slotLabelFormat={{ hour: '2-digit', minute: '2-digit', meridiem: false, hour12: false }} // 左侧时间格式
          weekNumbers // 显示一年中的第n周
          eventSources={[matchList]} // 数据源
          defaultTimedEventDuration={'01:00:00'} // 当没有设置endTime时的持续时间为1个小时
          displayEventEnd
          eventClick={eventClick}
        />
      </div>
    </PageHeaderWrapper>
  )
}

export default connect()(Calendar)

  数据源:Calendar/data.ts

export const matchList = [
  { id: '0', title: '周计划', start: '2022-03-19 06:30:00', type: 1 },
  { id: '2', title: '自建日程', start: '2022-03-22 09:00:00', type: 2 },
  { id: '3', title: '周计划', start: '2022-03-23 12:30:00', type: 1 },
  { id: '4', title: '周计划', start: '2022-03-24 08:30:00', type: 1 }
]

  样式:Calendar/index.less

.main {
  position: relative;
  padding: 30px;
  background-color: var(--theme-pro-table-bk);
  border-radius: 15px;
  box-shadow: var(--theme-pro-card-shadow);
  :global {
    .ant-btn.add {
      position: absolute;
      top: 30px;
      right: 30px;
      width: 100px;
      border-radius: 4px;
    }
    .fc {
      .fc-header-toolbar {
        .fc-toolbar-chunk {
          position: relative;
          > div {
            display: flex;
            align-items: center;
            > button.fc-button {
              display: flex;
              align-items: center;
              justify-content: center;
              width: 60px;
              height: 32px;
              padding: 0;
              line-height: 32px;
              background-color: transparent;
              border: none;
              box-shadow: 0 0;
              span.fc-icon {
                display: none;
              }
              // 上一周按钮
              &.fc-prevMap-button {
                position: absolute;
                left: 0;
                color: #416eff;
              }
              // 下一周按钮
              &.fc-nextMap-button {
                position: absolute;
                right: 0;
                color: #416eff;
              }
              // 被盖住的按钮:prev、next
              // &.fc-prev-button,
              // &.fc-next-button {
              //   opacity: 0;
              // }
            }
            > h2 {
              margin: 0 20px;
              color: var(--theme-text-color);
              font-size: 18px;
            }
          }
          > button.fc-button {
            position: absolute;
            top: 0;
            right: -100px;
            bottom: 0;
            width: 60px;
            height: 32px;
            margin-left: 0;
            line-height: 0;
            background-color: #416eff;
            border: none;
            box-shadow: 0 0;
            // 被盖住的按钮:today
            &.fc-today-button {
              display: none;
            }
          }
        }
      }
      .fc-view-harness .fc-scrollgrid {
        border-color: var(--theme-pro-table-border) !important;
        thead {
          tr {
            th {
              height: 40px;
              border-color: var(--theme-pro-table-border) !important;
              border-left: none;
              .fc-scroller {
                overflow: hidden !important;
                a {
                  color: var(--theme-text-color);
                  font-weight: 500;
                  font-size: 16px;
                  line-height: 36px;
                  cursor: default;
                }
              }
              &.fc-day-today {
                background-color: rgba(65, 110, 255, 0.1); // 今天背景色
                // background-color: #ecf1ff;
                a {
                  color: #416eff; // 今天
                }
              }
            }
          }
        }
        tbody {
          :global(.fc-day-grid-event .fc-content) {
            white-space: normal !important;
          }
          tr {
            td {
              height: 24px;
              border-color: var(--theme-pro-table-border) !important;
              .fc-scroller {
                // scrollbar-color: red transparent;
                /* 第一个方块颜色,第二个轨道颜色(仅火狐支持) */
                // scrollbar-width: thin;
                /* 使滚动条宽度变细(仅火狐支持) */
                // -ms-overflow-style: none;
                // 修改局部滚动条样式
                &::-webkit-scrollbar {
                  // width: 5px;
                }
                &::-webkit-scrollbar-thumb {
                  // background-color: #c1c1c1;
                }
              }
              .fc-timegrid-slots > table > tbody > tr:nth-child(2n) > td {
                border-top: none;
              }
              &.fc-timegrid-slot-label {
                color: var(--theme-text-color);
                font-size: 14px;
              }
              &.fc-day-today {
                background-color: rgba(65, 110, 255, 0.1); // 今天背景色
                // background-color: #ecf1ff;
              }
              .fc-timegrid-event-harness .fc-v-event {
                position: relative;
                // background-color: var(--theme-pro-table-bk);
                background-color: #fff;
                border: none;
                border-left: 4px solid;
                border-radius: 0 4px 4px 0;
                box-shadow: 2px 2px 4px 0 rgba(57, 78, 145, 0.1);
                .fc-event-main {
                  padding: 5px 0 5px 4px;
                  .fc-event-main-frame {
                    // color: var(--theme-text-color);
                    color: #373a44;
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
View Code

 

三、效果

  

 

四、重写切换周按钮事件

        <FullCalendar
          height={document.documentElement.offsetHeight - 150}
          initialView="timeGridWeek" // 初始化在week维度
          plugins={[dayGridPlugin, timeGridPlugin]}
          headerToolbar={{
            left: '',
            center: 'prevMap,prev,title,next,nextMap today todayMap',
            // center: 'prev,title,next today',
            right: ''
          }}
          locale="zh-cn"
          // buttonText={{ today: '今天', month: '月', week: '周', day: '天' }}
          allDaySlot={false} // 不显示all-day
          firstDay={6} // 从周六开始
          scrollTime={'06:00:00'} // 初始滚动条滚动到的时间位置:6点
          slotLabelFormat={{ hour: '2-digit', minute: '2-digit', meridiem: false, hour12: false }} // 左侧时间格式
          weekNumbers // 显示一年中的第n周
          eventSources={[list]} // 数据源
          defaultTimedEventDuration={'01:00:00'} // 当没有设置endTime时的持续时间为1个小时
          // displayEventEnd
          eventClick={handleDetail} // 点击打开详情
          // 自定义按钮,用来盖住原来的按钮,并且当前按钮点击时触发原来按钮的事件
          customButtons={{
            prevMap: { text: '上一周', click: handlePrevMap },
            nextMap: { text: '下一周', click: handleNextMap },
            todayMap: { text: '今天', click: handleTodayMap }
          }}
        />
  const [index, setIndex] = useState<number>(4) // 默认停留在当前周

  // 获取DOM
  const getDom = (className: string) => document.querySelector(className) as HTMLElement
  const prev = getDom('.fc-prev-button'),
    next = getDom('.fc-next-button'),
    today = getDom('.fc-today-button')

  // 上一周
  const handlePrevMap = () => {
    if (index === 0) {
      message.warning('已经是第一周')
    } else {
      prev.click()
      setIndex(index - 1)
    }
  }

  // 下一周
  const handleNextMap = () => {
    if (index === 6) {
      message.warning('已经是最后一周')
    } else {
      next.click()
      setIndex(index + 1)
    }
  }

  // 今天
  const handleTodayMap = () => {
    today.click()
    setIndex(4)
  }

  useEffect(() => {
    getList(index)
    const prevMap: any = getDom('.fc-prevMap-button'),
      nextMap: any = getDom('.fc-nextMap-button'),
      todayMap: any = getDom('.fc-todayMap-button')
    prevMap.disabled = index === 0 ? true : false
    nextMap.disabled = index === 6 ? true : false
    todayMap.disabled = index === 4 ? true : false
  }, [index])

 

posted @ 2022-03-23 14:47  吴小明-  阅读(656)  评论(0编辑  收藏  举报