最近要实现一个工作台日历(如下图),最后选择了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()
若你还要像我那样的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)
文章到这里基本结束了,有什么不懂的或者我写的不对的地方,欢迎交流!
- 2166
-
NoSilverBullet
Vue.js
- 1529
-
不懂韭菜的韭菜
JavaScript
Vue.js
- 194
-
zzjyr
Vue.js
React.js
- 135
-
凌晨花未眠
Element
掘金·日新计划