fullCalendar日程表在Vue项目中的应用

fullCalendar相关API

使用fullCalendar插件在项目中实现日程排版,支持天、月日程转换,自定义事件

页面布局

通过按钮切换天与月视图的转换,天视图回显具体的时分排版项目,月视图回显缩略信息

<div class="order-day-calendar h-100 clearfix"><div id='calendar' class="h-100" @contextmenu.prevent.stop="stop_default"></div><!-- 右键单击预约信息 --><right-menu ref="menu" :eventsource="menutop"><div slot="list"><p v-if="!isCurrentDate" @click="arriveModel('arrive')"><i class="iconfont icon-jinrudianpu"></i> 进店登记</p><p @click="lookOrderModel('lookorder')"><i class="iconfont icon-leijiyuyue"></i> 预约详情</p><p v-if="!isShow" @click="showModel('edit')"><i class="iconfont icon-icon-"></i> 修改预约</p><p v-if="!isShow" @click="cancelModel('concel')"><i class="iconfont icon-shanchu"></i> 取消预约</p><p @click="lookInfoModel('lookinfo')"><i class="iconfont icon-chakan"></i> 查看档案</p></div></right-menu><!-- 右键单击可排班区域的回显 --><right-menu ref="menu2" :eventsource="menutop"><div slot="list"><p @click="addOrder()"><i class="iconfont icon-zengjia"></i> 新增预约</p></div></right-menu><!-- 鼠标滑过预约信息 --><div ref="menu3" v-show="isshowpopover" class="tootips" :style="{top:menulocation.y + 'px',left:menulocation.x + 'px'}"><look-order-info :msg="look_msg" :labelWidth="'95px'"></look-order-info></div><!-- 详情信息组件 --><ele-close-order ref="closeorder" :info="item"></ele-close-order>
</div>

挂在日程组件

日程组件生成需要在dom挂载完毕之后进行,由于calendar是有jq实现的,所以项目需要配置jq的引用;

export default {name: 'calendar',data () {return {// 组件变量数据}}mounted(){// 初始化日程this.InitCalendar()},methods:{// 业务逻辑}
}

模拟数据

export default {name: 'calendar',data () {return {// 预约人orderlists:[{emp_adviser: '55',emp_advisername:'张三',status: '1',name: '张病人',bind_phone: '0101451213',date: '2022-04-30',start_time: '08:30',end_time: '11:30',e_serve: '常规检查'},{emp_adviser: '56',emp_advisername:'李四',status: '2',name: '张病人',bind_phone: '010-12154512',date: '2022-04-30',start_time: '14:30',end_time: '15:30',e_serve: '二次复查检查'},{emp_adviser: '57',emp_advisername:'王二',status: '3',name: '张病人',bind_phone: '010-12154512',date: '2022-04-30',start_time: '14:30',end_time: '15:30',e_serve: '一般检查'},{emp_adviser: '57',emp_advisername:'王二',status: '4',name: '李二狗',bind_phone: '124721847238',date: '2022-04-30',start_time: '11:30',end_time: '12:30',e_serve: '内科检查'},{emp_adviser: '56',emp_advisername:'李四',status: '2',name: '王砖头',bind_phone: '4512441',date: '2022-04-29',start_time: '11:30',end_time: '12:30',e_serve: '内科检查'}],// 值班人员allWorkTime:[{date: '2022-04-30',empid: '55',empname: '张三',day: '1'},{date: '2022-04-30',empid: '56',empname: '李四',day: '2'},{date: '2022-04-30',empid: '57',empname: '王二',day: '3'}],}}mounted(){// 初始化日程this.InitCalendar()},methods:{InitCalendar(){if(this.radio === 'day'){this.InitDayCalendar('agendaDay',{resources: this.getResources()});//由月切换到天,默认显示选择月的天$('#calendar').fullCalendar('gotoDate',this.currentTime);} else if (this.radio === 'month'){this.InitDayCalendar('month',{})}},// 生成成日表InitDayCalendar(type,object){const self = this;$('#calendar').fullCalendar( 'destroy' )const options = MyCalendar.options(type,500);$('#calendar').fullCalendar(Object.assign(options,object,{eventSources:MyCalendar.eventSources(self.orderlists,self.has_look_contact_auth),// 自定义事件逻辑}));// 重新计算日程表的高度this.getCalendarHeight();},// 计算日程表的高度getCalendarHeight(){try {this.timer_g ? clearTimeout(this.timer_g) : '' ;this.timer_g = setTimeout(() => {let in_h = $('#calendar').height();// console.log(in_h);$('#calendar').fullCalendar('option', 'height', (in_h - 10));}, 100);} catch (error) {myAlert('获取日程表高度失败!')}},}
}

实现工具函数

// MyCalendar.js
export default {filter: function (options) {let { list, rest, temptime, id, other,orderlist} = options;// 获取门店idconst store_id = '55';// 先检测是否休店for (let i = 0; i < rest.length; i++) {const ele = rest[i];if (ele.storeid == store_id && ele.date == temptime){return [{ id: '休店', title: '今日休店', day: '4'}]}}// 检测是预约列表中是否存在已被预约,但未排班的员工let get_c_time_adivers = orderlist.filter(item => item.date == temptime);// let get_c_time_adivers = [{ emp_adviser: '55', emp_advisername:'测试用的'}];// 不休店,则获取分类const arr = []list.forEach(item => {if (item.date == temptime) {// 检查是否存在已预约未排班的员工get_c_time_adivers = get_c_time_adivers.filter(order => order.emp_adviser != item.empid);other ? arr.push({ id: +item.empid, title: item.empname, day: item.day }) : arr.push(item);}});get_c_time_adivers.forEach(item => {other ? arr.push({ id: +item.emp_adviser, title: item.emp_advisername, day: '6' }) : '';});// console.log(get_c_time_adivers);// 合并排班for (let i = arr.length - 1; i >= 0; i--) {const item = arr[i];for (let j = i - 1; j >= 0; j--) {const ele = arr[j];if (ele[id] === item[id]) {ele.day = '3';arr.splice(i, 1);}}}if(arr.length === 0){return [{ id: '未排班', title: '今日未排班', day: '5' }]}return arr},// 参数options: function (type = 'agendaDay', height = 755){return {defaultView: type,groupByResource: true,header: false,height: height,aspectRatio: 2,allDayText: "未处理",            //自定义全天视图的名称slotDuration: "00:30:00",      //一格时间槽代表多长时间,默认00:30:00(30分钟)slotLabelFormat: "H:mm",    //日期视图左边那一列显示的每一格日期时间格式slotLabelInterval: "00:30:00",listDayFormat: false,listDayAltFormat: false,nowIndicator: true,minTime: '08:00:00',maxTime: '18:30:00',displayEventTime: false,firstDay: 1,editable: false,timeFormat: 'H:mm',axisFormat: 'H:mm',}},// 事件源eventSources: function (list, hasContactAuth){// 事件对象function getEvents(type) {const arr = [];list.forEach(item => {if (item.status == type) {// console.log(item);const time = item.date.split('-'),start_time = item.start_time.split(':'),end_time = item.end_time.split(':');let phone = hasContactAuth ? util.getCustomerPhone(item) : util.contact_replace(util.getCustomerPhone(item));let obj = {id: item.id,title: `<div class="clearfix word-task"><ul class="clearfix"><li>${item.name || item.c_name} <span>${phone}</span></li><li><em>服 务:</em>${item.e_serve || item.serve || '' }</li><li><em>时 间:</em>${item.date} ${item.start_time} - ${item.end_time}</li></ul></div>`,resourceId: +item.emp_adviser || +item.adviser,className: 'status status' + type + '-inner',data: item};if (item.start_time) {obj = Object.assign(obj, {start: new Date(time[0], time[1] - 1, time[2], start_time[0], start_time[1]),end: new Date(time[0], time[1] - 1, time[2], end_time[0], end_time[1]),allDay: false,})} else {obj = Object.assign(obj, {start: new Date(item.date),end: new Date(item.date),allDay: true,})}arr.push(obj)}});return arr;};const arr = [{events: getEvents(1),backgroundColor: '#0039fe',color: 'black',textColor: '#333',borderColor: "#f39c12"},{events: getEvents(2),textColor: '#333',backgroundColor: 'green',},{events: getEvents(3),backgroundColor: '#0039fe',textColor: '#333',borderColor: "#f39c12"},{events: getEvents(4),textColor: '#333',backgroundColor: '#ccc',},{events: getEvents(5),textColor: '#333',backgroundColor: '#ccc',}];return arr}
}

效果如下,默认视图为日视图

切换月视图如下:

自定义方法及事件

在初始化方法中的配置项中增加以下代码,配置自定义事件回调


dayClick : function( date, e, jsEvent, view ) {// console.log(date, view);if(!view) return false;const clickTime = new Date(date.format()).getHours();if(view.day == '1' && +clickTime > 11){tipsMsg(self, 'warning', '只能在上午排班!');return false} else if (view.day == '2' && +clickTime < 12){tipsMsg(self, 'warning', '只能在下午排班!');return false} else if(view.day == '4'){tipsMsg(self, 'error', '今日休店!');return false} else if(view.day == '5'){tipsMsg(self, 'error', '今日未排班!');return false} else if(view.day == '6'){tipsMsg(self, 'error', '预约权限已禁止!');return false}const target_ele = e.target;// const clickMiunt = new Date(date.format()).getMinutes() === 30 ? '30' : '00';// console.log(clickTime,clickMiunt);// 显示右键菜单self._showMenu(e,'menu2',{date:util.dateToggle('-','-','',date.format()),emp_adviser:view.id});
},
eventRender: function (event, element) {element.html(event.title);
},
eventClick : function(data, e, event){const temp_data = data.data;// console.log(temp_data);if(temp_data.status == '5' || temp_data.status == '4'){tipsMsg(self, 'error', '该预约已取消!');return false ;}self._showMenu(e,'menu',temp_data);
},
eventMouseover:function(data, e, event){console.log(data.data);self.look_msg = data.data;this.onmousemove = function(e){self.too_Tips(e);}
},
eventMouseout:function(data, e, event){self.outtootips();
},

methods中增加剩余逻辑代码

methods: {stop_default(){// 阻止默认事件},_showMenu(e,menu,item){this.item = item;this.menutop = e;this.$refs[menu].isShowMenu = true;this.isshowpopover = false;},showModel(e){// console.log(this.item);const obj = {isnew:false,orderInfo:this.item,title:'修改预约','weixin':true,'datelock':false,'url':'updatereservation',from:'day'}// 业务逻辑},arriveModel(arrive){Event.$emit('comeIn',Object.assign({},this.item,{isnew:false}));},cancelModel(concel){//取消预约this.$refs.closeorder.dialogVisible = true;},lookOrderModel(){//查看预约信息// 业务逻辑},lookInfoModel(){//查看档案// 业务逻辑},addOrder(){// console.log(this.item);const obj = {isnew:true,orderInfo:this.item,title:'新增预约','datelock':false,from:'day'}// Event.$emit('editOrder',obj);tipsMsg(this, 'success', '新增预约成功');},intootips(){clearInterval(this.timer);this.timer = setTimeout(() => {this.isshowpopover = true;}, 100);},outtootips(){clearInterval(this.timer);this.timer = setTimeout(() => {this.isshowpopover = false;}, 100);},// 获取tootiptoo_Tips(e){clearInterval(this.timer);this.isshowpopover = true;//获取tootip 父元素居body顶部与左侧的距离let ele_div = document.getElementsByClassName('order-day-calendar')[0];// 获取父级元素的滚动条let warp_ele = document.getElementsByClassName('my-data')[0];const p = util.getElePoint(ele_div);const e_current = e.currentTargetconst c = util.getElePoint(e_current);// 设置tootip的定位this.$nextTick(() => {let ele = this.$refs.menu3,dom_Width = ele.clientWidth,dom_Height = ele.clientHeight,dom_w = e_current.clientWidth,dom_h = e_current.clientHeight,client_W = document.body.clientWidth,client_H = document.body.clientHeight,dom_clientX = e.clientX,dom_clientY = e.clientY;let scroll = warp_ele.scrollTop;// 滚动条的高度let location = {y:dom_clientY - p.t + scroll ,x:dom_clientX - p.l + 20};if(dom_clientY + dom_Height > client_H){//如果菜单的高度 + 菜单距浏览器顶部的高度,大于浏览器视口高度location.y = location.y - dom_Height - dom_h/2;}if(dom_clientX + dom_Width > client_W - 50){location.x = location.x - dom_Width - 40;}this.menulocation = location;client_W = null;client_H = null;ele_div = null;warp_ele = null;});}
}

销毁日程

组件卸载时,需要销毁日程实例

beforeDestory(){this.$refs = {};$('#calendar').fullCalendar( 'destroy' )
}



fullCalendar日程表在Vue项目中的应用相关推荐

  1. canvas java 上传截图_在Vue项目中使用html2canvas生成页面截图并上传

    使用方法 项目中引入 npm install html2canvas html代码 //html代码 js代码 // 引入html2canvas import html2canvas from 'ht ...

  2. 如何在Vue项目中使用vw实现移动端适配(转)

    有关于移动端的适配布局一直以来都是众说纷纭,对应的解决方案也是有很多种.在<使用Flexible实现手淘H5页面的终端适配>提出了Flexible的布局方案,随着viewport单位越来越 ...

  3. 实战:vue项目中导入swiper插件

    版本选择 swiper是个常用的插件,现在已经迭代到了第四代:swiper4. 常用的版本是swiper3和swiper4,我选择的是swiper3. 安装 安装swiper3的最新版本3.4.2: ...

  4. vue ajax highcharts,在vue项目中引入highcharts图表的方法(详解)

    npm进行highchars的导入,导入完成后就可以进行highchars的可视化组件开发了 npm install highcharts --save 1.components目录下新建一个char ...

  5. VUE项目中使用this.$forceUpdate();解决页面v-for中修改item属性值后页面v-if不改变的问题

    VUE项目中使用this.$forceUpdate();解决页面v-for中修改item属性值后页面v-if不改变的问题 参考文章: (1)VUE项目中使用this.$forceUpdate();解决 ...

  6. 在vue项目中:统一封装 Axios 接口与异常处理

    在vue项目中:统一封装 Axios 接口与异常处理 参考文章: (1)在vue项目中:统一封装 Axios 接口与异常处理 (2)https://www.cnblogs.com/itgezhu/p/ ...

  7. vue php跨域,Vue 项目中遇到的跨域问题及解决方法(后台php)

    问题描述 前端 vue 框架,后台 php,百度跨域问题后台加这段代码 header("Access-Control-Allow-Origin: *"); 加了之后报这个错: Th ...

  8. Typescript在Vue项目中的使用

    最近尝试了一下Typescript在Vue项目中的使用,中间遇到了一些问题,把遇到的问题记录一下,以防被忘. 如何让Typescript识别Vue.JSON文件 因为Typescript默认不能识别. ...

  9. vue项目中使用echarts实现词云

    0.先上效果图 1.安装插件 -- vue项目中 npm install echartsnpm install echarts-wordcloud 2.vue页面中引入组件 <word-clou ...

  10. 【全栈项目上线(vue+node+mongodb)】06.nodejs服务上线(生产环境前后分离的vue项目中怎么解决跨域问题)...

    以下操作使用下面项目为案例 https://github.com/itguide/vnshop ## 启动node服务 克隆好项目后记得把依赖包安装好 npm i 使用 node 启动node服务 c ...

最新文章

  1. 再谈querySelector和querySelectorAll
  2. 从零开始Code Review
  3. 比特币官方客户端钱包是用什么语言开发的_『学概念找员外』比特币网络(三)...
  4. Vue监控器watch的全面解析
  5. context root修改无效:web修改项目路径(eclipse)
  6. Python 类的属性和实例属性 Python 的动态语言
  7. 单元测试和sit测试和uat测试
  8. 二进制编辑器BZ-1621网址
  9. 小管家进销存_美团入局共享充电宝,专家称或收购一两家,同行称雷声大雨点小...
  10. 华为p20位置服务器在哪打开,华为p20在哪里打开北斗定位 | 手游网游页游攻略大全...
  11. 「Golang」sync.Once用法以及源码讲解
  12. MATLAB麦克劳林展开式cosx,用matlab绘制e^x的泰勒展开式的图像
  13. Seaborn 绘图中设置字体及大小
  14. ABAQUS不能导入.x_t文件解决方法
  15. MySQL用户管理语句001
  16. 2021毛概知识点章节整理(完整版)
  17. 计算机科学类面试题,银行计算机类笔试题目
  18. LINK : fatal error LNK1104: 无法打开文件“mfc71.lib”的原因一例
  19. 深大数据库系统实验3——DATABASE SOFTWARE练习实验
  20. 11月8日google pr更新(今年第四次)

热门文章

  1. hapi.js_使用Hapi.js制作RESTful API
  2. bootstrap开发微信公众号后台界面
  3. c51为啥要宏定义时钟_C51 DS1302实时时钟的应用(2-26)
  4. Fiori 磁贴配置
  5. 讨论《蔚蓝(Celeste)》的设计
  6. 华为od与中软外包哪个更好_真惨!入职中软一个月(外包华为)就离职了~
  7. 华为外包的感受(CSDN)
  8. 静默安装oracle11g单实例-腾讯云
  9. 腾讯云云通信TLS后台API在mac上JAVA DEMO搭建
  10. excel复选框_在Excel公式中使用复选框结果