最近要实现一个工作台日历(如下图),最后选择了fullcalendar。

它是基于Jquery的,目前也支持vue,但是例子好像不多,且文档是英文的,某些对于方法属性的说明也不尽完全,大大增加了使用难度。所以写这个文档简单说明下某些场景下我们应该怎么做。

下面说下使用方法和各属性的含义:

我用的是vue3,先安装必须模块,其他的插件模块可根据需要选择。如:dayGridPlugin,listPlugin

npm install --save @fullcalendar/vue3 @fullcalendar/core  @fullcalendar/daygrid  @fullcalendar/list

2.引入需要的插件模块,常用配置,注意看下面注释

<script lang="ts" setup>import '@fullcalendar/core/vdom' // solve problem with Viteimport FullCalendar, { EventClickArg } from '@fullcalendar/vue3'import dayGridPlugin from '@fullcalendar/daygrid'import listPlugin from '@fullcalendar/list'const calendarOptions = ref({  locale: 'zh-cn', // 设为中文  plugins: [    dayGridPlugin, // 包含dayGridDay,dayGridMonth 和 dayGridWeek    listPlugin, // 日的列表视图需要的    interactionPlugin // 日期点击事件需要的  ],  headerToolbar: false, // 这里隐藏掉了默认头部工具栏,方便自定义  allDayText: '任务', // 设置全天事件文本,默认allday
  allDaySlot: true, // 不显示all-day  initialView: 'dayGridMonth', // 初始化渲染的日历视图  // initialEvents: INITIAL_EVENTS, // 默认的日历事件列表,即数据源  aspectRatio: 1.52, // 宽高比---这个比例很重要,根据日历大小进行调节,比例不够会渲染成...,而不是一个任务条  selectable: true, // 是否可被选择
  selectMirror: true, //在用户拖动时绘制“占位符”事件  dayMaxEvents: true, // 给定日期内的最大事件数,不包括+more链接,如果指定为true,则事件的数量将限制为日单元格的高度  moreLinkContent: '...', // 事件过多时将+more 文本修改成自己想要的  rerenderDelay: 200,  eventClick(clickInfo: EventClickArg) { // 点击任务事件    emit('lookDetail', clickInfo.event.id)  },  handleWindowResize: false, // 是否根据窗口改变  eventLimitText() { // 设置日历事件超出限制条数的文本    return ''  },  views: { // 各视图的个性化设置    dayGridMonth: { // 月视图      displayEventTime: false,      moreLinkClick() { // 点击...触发的事件             const calendarApi = fullCalendar!.value.getApi()        dataType.value = true        nextTick(() => {          title.value = calendarApi.view.title        })        return 'listDay' // 点击后跳转日的列表这个是重点      }    }  }})</script>

因需要点击三个点跳转到日视图查看列表,所以需要我们在dayGridMonth的里面添加点击事件,并实现效果,经阅读发现可以通过返回‘listDay'来实现

dayGridMonth: {      ...      moreLinkClick() {        const calendarApi = fullCalendar!.value.getApi()  // 获取日历的实例        nextTick(() => {          title.value = calendarApi.view.title // 修改日历的title        })        return 'listDay'      }          }

若你还要像我那样的hover效果,我们就要借助tippy.js了

npm i tippy.js
import tippy from 'tippy.js';
import 'tippy.js/dist/tippy.css';
import 'tippy.js/themes/light.css';

然后在dayGridMonth里面添加 hover事件

重点!!!,一定要选对挂载元素,一定要在隐藏的时候销毁,不然一直累加投影效果,与UI不符

dayGridMonth: {     ...      eventMouseEnter(info) {        tippy(info.el, {          content: info.event.title, // hover标题          theme: 'light', // 主题          maxWidth: 350,          duration: 500,          onHidden(info) {             info.destroy() // 一定要!!!            return false          }        })      }          }
<FullCalendar :options="calendarOptions" ref="fullCalendar">

3.方法调用

我们是自定义的头部,所以需要手动切换相关主题,此时就用到了FullCalendar的api

切换视图changeView(), 后一天/月next() ,前一天/月prev()

但是我们又不能直接在setup 里面获取,因为此时它还没有获取到完整实例,可以在对应执行的方法里面获取

<div class="select">        <el-radio-group          style="margin-bottom: 20px"          v-model="dataType"          @change="changeType"        >          <el-radio-button :label="false">月</el-radio-button>          <el-radio-button :label="true">日</el-radio-button>        </el-radio-group>      </div>
// jsconst changeType = async () => {  const calendarApi = fullCalendar!.value.getApi()  if (dataType.value) {    calendarApi.changeView('listDay')  } else {    calendarApi.changeView('dayGridMonth')  }  title.value = calendarApi.view.title    await getData() // 从后端获取的数据}

calendarApi.next(), calendarApi.prev() 也是如此!

4.events数据源的设置

很多人会遇到这个问题,就是明明数据源更新了,视图却没有更新,即使声明为ref()也不行

那是因为你的数据不是动态的,此时需要我们用到它的另外一个API  setOption

calendarApi.setOption('events', arr)

文章到这里基本结束了,有什么不懂的或者我写的不对的地方,欢迎交流!

分类:
前端
  •