一、下载依赖
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 { // 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; } } } } } } } } } }
三、效果
四、重写切换周按钮事件
<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])