Fullcalendar V5踩坑 (日视图篇)

Vue项目使用

 

<template>
  <div class="M_container">
    <FullCalendar
      class="fullcalendar"
      ref="myCalendar"
      :options="calendarOptions"
    >
    </FullCalendar>
   
  </div>
</template>
 
<script>

import { GetDayList } from "@/api/schedule/index";
import {formateDate} from "@/utils/schedule/formate";
import FullCalendar from "@fullcalendar/vue";
import dayGridPlugin from "@fullcalendar/daygrid";
import timeGridPlugin from "@fullcalendar/timegrid";
import interactionPlugin from "@fullcalendar/interaction";
import {eventContetFun,changeStartEnd,slotLabelContent,eventMouseEnter} from "@/utils/schedule/fullcalendarHandler"
export default {
  name: "byDay",
  components: {
    FullCalendar
  },
  props:['filterDate'],
  data() {
    return {
      selectDate:'',
      calendarOptions: {
        plugins: [dayGridPlugin, interactionPlugin, timeGridPlugin],
        initialView: "timeGridDay",
        events: [],
        locale: "zh-cn", 
        themeSystem: "bootstrap", // 主题色(本地测试未能生效)expandRows: true,
        expandRows: true,
        contentHeight: 870,
        timeGridEventMinHeight: "26", // 设置事件的最小高度
       // 设置日历单元格宽度与高度的比例。
        eventLimit: true, // 设置月日程,与all-day slot的最大显示数量,超过的通过弹窗显示
        headerToolbar: false,
        allDaySlot: true,
        allDayText: "全天",
        scrollTimeReset:true,
        scrollTime:"12:00:00",
        slotDuration:"01:00",
        slotMinTime: "07:00:00",
        slotMaxTime: "20:00:00",
        dayHeaders: false,
        slotEventOverlap: false,//是否重叠
        showNonCurrentDates: false,
        eventMouseEnter:eventMouseEnter,
        slotLabelContent:slotLabelContent,
        eventContent:eventContetFun, 
        views: {
          timeGridDay: {
            eventLimit:5,
            dayMaxEventRows: 4, 
           /*  eventMaxStack:30, */
            moreLinkContent: "更多",
            moreLinkClick: "popover",
          },
        },
        slotLabelFormat: {
          hour: "2-digit",
          minute: "2-digit",
          meridiem: false,
          hour12: false, // 设置时间为24小时
        },
        eventLimitNum: {
          // 事件显示数量限制(本地测试未能生效)
          dayGrid: {
            eventLimit: 3,
          },
          timeGrid: {
            eventLimit: 2, // adjust to 6 only for timeGridWeek/timeGridDay
          },
        },
        eventClick: this.handleEventClick,
      },
    };
  },
   watch: {
    filterDate: {
      handler(newValue,oldValue) {
        if(newValue&&newValue!=oldValue){ 
         /*  this.$emit('changeDayDate',newValue); */
         this.selectDate=newValue;
          this.getDayData();
          }else{
          this.$alert("请选择日期", "提示");
        }
      },
      immediate: true
    },
  },
  mounted() {
      this.$nextTick(()=>{
         this.selectDate=this.filterDate;
      })
  },
  methods: {
    changeSelect(){
       this.$emit('changeDayDate',this.selectDate);
    },
    getDayData() {
      const _this = this;
      this.$nextTick(()=>{
        let calendarApi = this.$refs.myCalendar.getApi(); 
        calendarApi.gotoDate( _this.filterDate );
      })
      GetDayList({
        startDate: _this.filterDate,
      }).then((res) => {
        let resData = res.data,
          result = resData.flat(Infinity);
         const handleData = result.map((item) => {
          let timeObj=changeStartEnd(_this.filterDate,item); 
         return {
            start: timeObj.itemStart,
            end: timeObj.itemEnd,
            startTimes:new Date(item.startTime?item.startTime:item.allDayStartTime),
            endTimes:new Date(item.endTime?item.endTime:item.allDayEndTime),
            title: item.sysScheduleContent,
            classNames: item.actualCompleteTime ? "blue" : "orange",
            sysScheduleArrangeAllRecordId:item.sysScheduleArrangeAllRecordId,
            sysScheduleArrangeId:item.sysScheduleArrangeId,
            status:item.status,
            actualCompleteTime:item.actualCompleteTime,
            important:item.important,
          };
        });
      
        _this.calendarOptions.events =handleData;
        
      });
    },
    /**
     * 点击日历日程事件
     *
     * info: 事件信息
     * event是日程(事件)对象
     * jsEvent是个javascript事件
     * view是当前视图对象。
     */
    handleEventClick(info) {
      const data=info.event._def.extendedProps;
      const scheduleID={sysScheduleArrangeAllRecordId:data.sysScheduleArrangeAllRecordId,sysScheduleArrangeId:data.sysScheduleArrangeId,status:data.status};
      this.$emit('getScheduleID',scheduleID)
    },
  },
};
</script>

依赖包版本如下

 页面效果:

 纵坐标时间轴处理:

首先,设置

        slotMinTime: "07:00:00",

        slotMaxTime: "20:00:00",

设置后08:00-18:00前后只剩下一格位置,再结合slotLabelContent:function(arg){}对时间轴文字处理

function slotLabelContent(arg){
  if (Number(arg.time.milliseconds) < 28800000) {
    return "08:00前";
  }
  if (
    Number(arg.time.milliseconds) >= 28800000 &&
    Number(arg.time.milliseconds) <= 64800000
  ) {
    return arg.text;
  }
  if (Number(arg.time.milliseconds) > 64800000) {
    return "19:00后";
  }
}

这下出现了20:00后或者07:00前的数据无法呈现,因为该部分时间并没有对应的时间轴

这时候就要对Events:[]的数据进行处理,同时结合eventContent:function(arg){}

以下代码是对start和end进行处理

function changeStartEnd(day, item) {
  if(item.startTime&&item.endTime){//非全天
    let startTime = new Date(day + " " + '08:00');
    let endTime = new Date(day + " " + '20:00');
    let endTime1 = new Date(day + " " + '19:00');
    let itemStart = new Date(item.startTime);
    let itemEnd = new Date(item.endTime);
    if (itemStart < startTime) {
      itemStart = new Date(day + " " + '07:00');
    }
    if (itemStart > endTime1) {
      itemStart = new Date(day + " " + '19:00')
    }
    if (itemEnd < startTime) {
      itemEnd = startTime;
    }
    if (itemEnd > endTime1) {
      itemEnd = endTime;
    }
    if(new Date(itemEnd)-new Date(itemStart)==0){//开始时间和结束时间一样 只占用半格
      let Hour=itemStart.getHours()<10?'0'+itemStart.getHours():itemStart.getHours()
      let time=itemStart.getFullYear()+"-"+(itemStart.getMonth()+1)+"-"+itemStart.getDate()+" "+Hour
      itemStart=time+":00";
      itemEnd=time+":30"
    }
    return {itemEnd,itemStart}
  }else{//全天日程
    return {
      itemStart:item.allDayStartTime,
      itemEnd: item.allDayEndTime
    }
  }
  
}

startTimes和endTimes用于页面文字展示时间段

fullcalendar插槽的使用

 1.自定义dayHeaderContent

<FullCalendar
      ref="fullCalendar"
      class="fullcalendar week"
      :options="calendarOptions"
    >
    <template v-slot:dayHeaderContent='arg'>
      <div class="top"  @click="changeToDay(arg.date)">
        {{arg|formateHeaderContent}}
        <span v-if="weekEventNumObj[arg.dow]>1" class="moreTips">更多日程</span>
       </div>
    </template> 
    </FullCalendar>

2.自定义eventContent

<template v-slot:eventContent='arg'>
        <el-tooltip
            class="box-item"
            effect="dark"
            placement="top-start"
        >
          <template #content>
            <span>
              {{ parseTime(arg.event.start,'{m}月{d}日 {h}:{i}') }}-{{ parseTime(arg.event.end,'{m}月{d}日 {h}:{i}') }} 预约时长:{{arg.event.extendedProps.num}}小时</span>
          </template>
          <div :class="[type !='check' ? 'text-box':'text-box check']">
            <span @click="changeInfo(arg.event)">
             {{ parseTime(arg.event.start,'{m}月{d}日') == parseTime(arg.event.end,'{m}月{d}日') ? parseTime(arg.event.start,'{h}:{i}') : parseTime(arg.event.start,'{m}月{d}日 {h}:{i}') }} -
              {{ parseTime(arg.event.end,'{m}月{d}日') == parseTime(arg.event.start,'{m}月{d}日') ? parseTime(arg.event.end,'{h}:{i}') : parseTime(arg.event.end,'{m}月{d}日 {h}:{i}')}}
             时长:{{arg.event.extendedProps.num}}h
          </span>
            <el-button v-if="type !='check'" type="danger" circle @click="deleteItem(arg.event.id)"><el-icon size="10"><close-bold /></el-icon></el-button>
          </div>
        </el-tooltip>
</template>
<template v-slot:eventContent="arg">
              <el-popover
                :append-to-body="true"
                ref="popover1"
                placement="top-start"
                width="220"
                :visible-arrow="true"
                trigger="hover"
                :teleported="false"
                popper-class="popover"
                :open-delay="100"
                @show="showPic(arg)"
                @hide="popoverPicReset(arg)"
              >
                
              </el-popover>
</template>

3.自定义slotLabelContent

tips:  slotDuration:"01:00",设置为一个小时,时间垂直居中显示,不然偏上

<FullCalendar
      ref="fullCalendar"
      class="fullcalendar week"
      :options="calendarOptions"
    >
    <template v-slot:slotLabelContent='arg'>
      <div class="top"  @click="changeToDay(arg.date)">
        {{arg|formateHeaderContent}}
        <span v-if="weekEventNumObj[arg.dow]>1" class="moreTips">更多日程</span>
       </div>
    </template> 
    </FullCalendar>

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值