FullCalendar日历组件集成实战(16)

背景

有一些应用系统或应用功能,如日程管理、任务管理需要使用到日历组件。虽然Element Plus也提供了日历组件,但功能比较简单,用来做数据展现勉强可用。但如果需要进行复杂的数据展示,以及互动操作如通过点击添加事件,则需要做大量的二次开发。
FullCalendar是一款备受欢迎的开源日历组件,以其强大的功能而著称。其基础功能不仅免费且开源,为开发者提供了极大的便利,仅有少量高级功能需要收费。然而,尽管该组件功能卓越,其文档却相对简洁,导致在集成过程中需要开发者自行摸索与探索,这无疑增加了不少学习和验证的时间成本。
为此,本专栏通过日程管理系统的真实案例,手把手带你了解该组件的属性和功能,通过需求导向的方式,详细阐述FullCalendar组件的集成思路和实用解决方案。
在介绍过程中,我们将重点关注集成要点和注意事项,力求帮助开发者在集成过程中少走弯路,提供有效的避坑指南,从而提升开发效率,更好地利用这款优秀的日历组件。

官网:https://fullcalendar.io/
image.png
环境Vue3+Element Plus+FullCalendar 6.1.11。

使用

保持当前视图范围不变

当我们在月底使用日历组件制定下个月计划和日程,或者安排下周的工作,新增或修改事件后,后端数据持久化后通过刷新页面的方式来让日历组件上的数据更新。这样存在的问题在于一旦刷新页面,则日历组件会“跳”回到当天日期。
例如,制定6月份的计划,刚添加了1条数据,然后保存,视图又跳回了5月份,还需要手工再切换,明显不合理。

FullCalendar组件的切换视图的方法changeView,可以传入第二个参数,单个时间或者起止范围。

在前面的实现方式中,我们通过query参数保持当前的视图类型以及自定义的显示范围(全部任务/进行中任务),采用该方式,把当期视图的显示时间范围也通过query参数来传递,在刷新方法中处理:

    // 刷新refresh() {const fullCalendar = this.$refs.fullCalendar.calendar// console.log(fullCalendar.view)let query = this.$route.queryquery = Object.assign(query, {viewType: fullCalendar.view.type,showAllFlag: this.showAllFlag,start: this.$dateFormatter.formatUTCDate(fullCalendar.view.activeStart),end: this.$dateFormatter.formatUTCDate(fullCalendar.view.activeEnd)})refreshSelectedTagWithQuery(query)}

然后在页面初始化时读取query参数,调用切换视图方法:

    // 初始化init() {this.calendarApi = this.$refs.fullCalendar.getApi()// 处理是否显示全部if (this.$route.query.showAllFlag != undefined) {//此处注意,query参数是字符串类型,直接赋值给showAllFlag会令其类型变化,使用非运算符!会一直为truethis.showAllFlag = this.$route.query.showAllFlag == 'true' ? true : false}// 默认设置视图类型let viewType = this.calendarOptions.initialView// query参数中取值if (this.$route.query.viewType) {viewType = this.$route.query.viewType}const fullCalendar = this.$refs.fullCalendar.calendarfullCalendar.changeView(viewType, {start: this.$route.query.start,end: this.$route.query.end})}

然后测试发现无效,依然显示的是当前时间。

然后手工写死测试,视图类型为日视图,传入单天,有效。

fullCalendar.changeView('timeGridDay', '2024-06-10')

视图类型为周,传入时间范围,无效!

 fullCalendar.changeView('timeGridWeek', { start: '2024-06-10', end: '2024-06-17' })

这就很无语了……
翻看了FullCalendar源码,看上去也没有问题:

changeView(viewType, dateOrRange) {this.batchRendering(() => {this.unselect();if (dateOrRange) {if (dateOrRange.start && dateOrRange.end) { // a rangethis.dispatch({type: 'CHANGE_VIEW_TYPE',viewType,});this.dispatch({type: 'SET_OPTION',optionName: 'visibleRange',rawOptionValue: dateOrRange,});}else {let { dateEnv } = this.getCurrentData();this.dispatch({type: 'CHANGE_VIEW_TYPE',viewType,dateMarker: dateEnv.createMarker(dateOrRange),});}}else {this.dispatch({type: 'CHANGE_VIEW_TYPE',viewType,});}});
}

停下来思考,推测日历展示的范围,不仅仅跟时间范围有关系,还跟目标时间有关系。
尝试调用内置方法gotoDate,源码调整如下:

  // 初始化init() {this.calendarApi = this.$refs.fullCalendar.getApi()// 处理是否显示全部if (this.$route.query.showAllFlag != undefined) {//此处注意,query参数是字符串类型,直接赋值给showAllFlag会令其类型变化,使用非运算符!会一直为truethis.showAllFlag = this.$route.query.showAllFlag == 'true' ? true : false}// 默认设置视图类型let viewType = this.calendarOptions.initialView// query参数中取值if (this.$route.query.viewType) {viewType = this.$route.query.viewType}const fullCalendar = this.$refs.fullCalendar.calendarif (this.$route.query.start && this.$route.query.end) {fullCalendar.changeView(viewType, {start: this.$route.query.start,end: this.$route.query.end})// 取起止范围相差天数const dayCount = this.getDaysDifference(this.$route.query.start, this.$route.query.end)// 开始时间加上时间范围差值的一半,即取时间中间位置const targetDay = new Date(new Date(this.$route.query.start).getTime() + (dayCount / 2) * 24 * 60 * 60 * 1000)// 导航到指定日期fullCalendar.gotoDate(this.$dateFormatter.formatUTCDate(targetDay))} else {fullCalendar.changeView(viewType)}}

实现的关键逻辑就是获取到页面刷新前视图显示的起止时间范围,然后取中间的时间值,调用api跳转到该时间。
对于日视图和周视图,跳转时间直接取开始时间也可以正常运行,但是月视图不行,因为默认显示范围大于一个月,当前月以及上个月底的几天和下个月的前几天都会显示。如果也直接取开始时间作为跳转时间,则还是会出现在月底制定下个月计划时,页面刷新跳回到本月的情况。

通过以上方法,前端功能正常了,监控后端服务,调用gotoDate时,又触发了一次加载数据,也就是刷新页面,需要加载三次数据……组件自己初始化触发一次,调用切换视图触发一次,调用跳转到时间再触发一次。
这么做确实不优雅,相当于曲线救国,不清楚是组件自身问题或限制,只能这么干,还是有更好的实现方案,后续解决了再更新下本文。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/34467.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux上使用 git 命令行

在 Github或者 gitee 注册账号 这个比较简单 , 参考着官网提示即可 . 需要进行邮箱校验.以下以创建Github为例。 创建项目 1. 登陆成功后 , 进入个人主页 , 点击下方的 create a new repository 按钮新建项目 2. 在创建好的项目页面中复制项目的链接 , 以备接下来进行下…

10分钟掌握Python缓存,效率提升1000%

全文速览 python的不同缓存组件的使用场景和使用样例cachetools的使用 项目背景 代码检查项目,需要存储每一步检查的中间结果,最终把结果汇总并写入文件中 在中间结果的存储中 可以使用context进行上下文的传递,但是整体对代码改动比较大…

Linux系统中文件权限详解

一、Linux文件权限设计 Linux系统中任何内容都可以用文件表示,其对文件设计了一套权限进行管理;文件权限共有11个字符,从左向右共分为5段(每段的具体说明如下表Linux权限设计说明所示): Linux权限设计说明 …

揭秘:企业如何防盗版软件

在当前的数字化时代,软件盗版问题一直困扰着软件开发者和企业。为了维护软件的合法权益,保护创新成果,许多企业采取了各种技术手段来防止软件被非法复制和分发。其中,白名单机制作为一种有效的防盗版软件手段,被广泛采…

书酒共舞:品味文字之韵,沉醉酒香之境

在喧嚣的都市中,我们常常渴望找到一片宁静的角落,让心灵得到片刻的休憩。此刻,一杯雷盛红酒与一本心仪的书籍,便成了很好的伴侣,它们相互映衬,共同编织出一幅优雅的画卷,让我们在品味中感受文字…

数据处理神器Elasticsearch_Pipeline:原理、配置与实战指南

文章目录 📑引言一、Elasticsearch Pipeline的原理二、Elasticsearch Pipeline的使用2.1 创建 Pipeline2.2 使用 Pipeline 进行索引2.3 常用的 Processor 三、实际应用场景3.1 日志数据处理3.2 数据清洗和标准化3.3 数据增强 四、最佳实践4.1 性能优化4.2 错误处理4…

Fusion WAN:企业出海与全球组网的数字网络底座

众多中国企业与品牌正将目光投向海外市场,积极寻求发展新机遇,并且在这一过程中取得了显著的成果。"出海"战略已经成为一些企业转型升级的关键选择。 随着国内市场的竞争日益激烈,越来越多的企业开始寻求海外市场的拓展&#xff0c…

11年之约 聚焦上海 | 亚信科技邀您相约2024 MWC上海展

关于亚信安慧AntDB数据库 AntDB数据库始于2008年,在运营商的核心系统上,服务国内24个省市自治区的数亿用户,具备高性能、弹性扩展、高可靠等产品特性,峰值每秒可处理百万笔通信核心交易,保障系统持续稳定运行超十年&a…

深入理解PHP命名空间

在PHP项目中,命名空间(namespace)是一个非常重要的特性。它不仅帮助开发者组织代码,还能避免类、函数、常量等命名冲突问题。本文将详细介绍PHP命名空间的概念、使用方法和最佳实践。 一、什么是命名空间? 命名空间…

windows@局域网或蓝牙文件传输@共享文件夹@就近共享

文章目录 windows系统下的简单共享文件方案👺就近共享设置共享文件夹(推荐)方法1:使用shrpubw程序引导创建方法2:使用图形界面创建右键设置共享文件夹 查看所有已经共享的文件夹👺停止某个文件的共享 共享文件夹的访问控制补充匿名访问问题😊…

10个国内免费AI绘画网站汇总【2024最新】

迎战MidJourney和Stable Diffusion:10款国产AI绘画神器,让你轻松创作出超凡艺术品!不论你是初学者还是资深艺术家,这些AI绘画平台都能帮你轻松入门。快来探索这些AI绘画网站,释放你的创意潜能! 1、AI绘画创…

flex属性中的flex-grow、flex-shrink、flex-basis

flex-grow 属性 flex-grow 属性用于设置或检索弹性盒子的扩展比率。 默认值为0&#xff0c;表示不伸展。 flex-grow属性值为0时&#xff0c;不伸展&#xff1a; <!doctype html> <html lang"en"><head><style>.d-flex {display: flex;width…

C语言——链表专题

乐观学习&#xff0c;乐观生活&#xff0c;才能不断前进啊&#xff01;&#xff01;&#xff01; 我的主页&#xff1a;optimistic_chen 我的专栏&#xff1a;c语言 点击主页&#xff1a;optimistic_chen和专栏&#xff1a;c语言&#xff0c; 创作不易&#xff0c;大佬们点赞鼓…

IP地址定位技术的广泛应用

IP地址定位技术是一种通过分析网络设备所使用的IP地址来确定其地理位置的地址技术手段。 IP地址定位技术基于互联网服务提供商&#xff08;ISP&#xff09;所分配的IP地址范围以及相关的地理信息数据库。当一个设备连接到网络并使用特定的IP地址进行通信时&#xff0c;IP地址定…

上海慢病管理app开发的意义及功能

近年来&#xff0c;随着经济与科技的不断发展&#xff0c;人们对慢性疾病的重视程度也不断提高。大家不再满足于周期较长的定期检查&#xff0c;而是渴求能够进行短期、实时的病情预防与监测&#xff0c;为了满足人们的需求&#xff0c;帮助大家更好的干预病情&#xff0c;上海…

AI智能体的炒作与现实:GPT-4都撑不起,现实任务成功率不到15%

AI 智能体的宣传很好&#xff0c;现实不太妙。 随着大语言模型的不断进化与自我革新&#xff0c;性能、准确度、稳定性都有了大幅的提升&#xff0c;这已经被各个基准问题集验证过了。 但是&#xff0c;对于现有版本的 LLM 来说&#xff0c;它们的综合能力似乎并不能完全支撑得…

云原生技术峰会:引领智能算力时代的创新浪潮

云原生技术峰会&#xff1a;引领智能算力时代的创新浪潮 随着云计算技术的飞速发展和智能算力的不断提升&#xff0c;云原生架构已成为推动企业数字化转型的重要力量。近日&#xff0c;一场汇聚了业界顶尖专家和学者的云原生技术峰会成功举行&#xff0c;与会者共同探讨了云原…

【Linux】常用基本命令

wget网址用于直接从网上下载某个文件到服务器&#xff0c;当然也可以直接从网上先把东西下到本地然后用filezilla这个软件来传输到服务器上。 当遇到不会的命令时候&#xff0c;可以使用man “不会的命令”来查看这个命令的详细信息。比如我想要看看ls这个命令的详细用法&…

canvas : Cannot read properties of null (reading ‘getContext‘)

获取 canvas 元素的 getContext 方法时&#xff0c;canvas 元素尚未正确绑定。可以通过确保在渲染 PDF 文件之前&#xff0c;canvas 元素已经正确挂载到 DOM 来解决这个问题。 解决方法 确保 pdfCanvas 引用已经绑定到正确的 DOM 元素。确保在渲染 PDF 文件时&#xff0c;can…

【模型】5分钟了解决策树是一个什么模型

本站原创文章&#xff0c;转载请说明来自《老饼讲解-机器学习》[www.bbbdata.com(https://www.bbbdata.com/ml) 决策树模型是机器学习中不可不学的模型之一&#xff0c;本文简单直接地快速讲解决策树是什么&#xff0c;如何实现。 一、决策树模型 决策树一般包括ID3决策树&am…