vue中使用FullCalendar实现自由拖拽日历活动(包含获取当前视图开始时间与结束时间,动态渲染接口日历活动数据)

2023-11-13

具体实现效果图如图所有:
在这里插入图片描述

1、安装FullCalendar相关插件

npm install --save "@fullcalendar/core"
npm install --save "@fullcalendar/interaction"
npm install --save "@fullcalendar/daygrid"
npm install --save "@fullcalendar/vue"

在这里插入图片描述
2、引用,静态数据进行拖拽(此时没有请求任何接口)

<FullCalendar ref="fullCalendar" :options="calendarOptions"/>
import '@fullcalendar/core/vdom' // solves problem with Vite
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin, { Draggable } from '@fullcalendar/interaction'
export default {
  name: 'TradingTimeManage',
  components: {
    FullCalendar
  },
  data() {
    return {
      eventEl: null,
      calendarOptions: { //?拖拽日历配置
        plugins: [dayGridPlugin, interactionPlugin],
        firstDay: 1, // 把每周设置为从周一开始
        header: { // 日历头部
          left: 'prev,next today',
          center: 'title',
          right: 'custom'
        },
        /* 设置按钮文字 */
        buttonText:{
          today:'今天',
        },
        initialView: 'dayGridMonth',
        locale: 'zh-cn', //? 配置中文
        selectable: true,//可编辑
        // dayMaxEvents: true,
        slotMinutes: 15,
        editable: false, // 日历上是否可拖拽
        droppable: true,
        dropAccept: '.list-group-item',
        drop: this.drop,
        },
        events: []
      },
      list: [
        { name: '工作日', value: '1', color: 'green' },
        { name: '春节放假', value: '7', color: 'blue' },
        { name: '中秋节放假', value: '3', color: 'blue'  },
        { name: '国庆节放假', value: '7', color: 'blue'  },
        { name: '游玩', value: '7', color: 'blue'  },
      ]
    }
  },
  mounted() {
    var containerEl = document.getElementById('list-group-item');
    // 初始化外部事件
    new Draggable(containerEl, {
        itemSelector: '.list-group-item',
      }
    )
  },
  methods: {
    drop(date, allDay) {
      this.calendarOptions.events.push({ // add new event data
        title: date.draggedEl.firstChild.innerHTML,
        start: date.dateStr,
        end: moment(date.dateStr).add(date.draggedEl.lastChild.innerHTML, 'days').format('YYYY-MM-DD')
      })
    }
  }
}

3、 获取当前日历视图开始时间、结束时间

 // 获取当前视图日历的范围
      const time = this.$refs.fullCalendar.getApi().currentDataManager.state.dateProfile.renderRange
      this.start = Date.parse(moment(time.start).format()) // 视图开始时间
      this.end = Date.parse(moment(time.end).format()) // 视图结束时间

4、上月、下月、今天添加事件

 calendarOptions: { //?拖拽日历配置
        customButtons: {
          prev: {
            // this overrides the prev button
            text: "PREV",
            click: () => {
              this.prevMethod();
            },
          },
          next: {
            // this overrides the next button
            text: "PREV",
            click: () => {
              this.nextMethod();
            },
          },
          today: {
            text: "今天",
            click: () => {
              this.todayMethod();
            },
          },
        },
      },



 /** 上个月  */
    prevMethod() {
      this.$refs.fullCalendar.getApi().prev() // 更新上个月视图
      console.log(this.$refs.fullCalendar.getApi().currentDataManager.state.dateProfile.renderRange)
    },
    /** 下个月  */
    nextMethod() {
      this.$refs.fullCalendar.getApi().next() // 更新下个月视图
      console.log(this.$refs.fullCalendar.getApi().currentDataManager.state.dateProfile.renderRange)
    },
    /** 今天  */
    todayMethod() {
      this.$refs.fullCalendar.getApi().today() // 更新今天视图
      console.log(this.$refs.fullCalendar.getApi().currentDataManager.state.dateProfile.renderRange)
    },

5、 请求接口,动态回显日历活动方法

 /** 获取视图活动数据方法 */
    holidayEvent(){
      // 获取当前视图日历的范围
      const time = this.$refs.fullCalendar.getApi().currentDataManager.state.dateProfile.renderRange
      this.start = Date.parse(moment(time.start).format()) // 视图开始时间
      this.end = Date.parse(moment(time.end).format()) // 视图结束时间
      // 从接口获取数据,更新日历视图活动
      holidayItem({ start: this.start, end: this.end }).then((res)=> {
        if (res.status === '200') {
          const data = res.data
          const arr = []
          data.forEach(item => {
             const obj = {
               id: item.id,
               title: item.name,
               start: item.day,
               end: item.dayEnd,
               allDay: true,
               backgroundColor: item.name === '工作日' ? 'green' : '#3788d8'
             }
             arr.push(obj)
          })
          this.calendarOptions.events = arr
        }
      })
    },

7、完整的拖动日历代码(包含请求接口)

<!--交易时间管理 -->
<template>
  <div class="container">
    <el-row :gutter="30">
      <el-col :span="8">
        <div class="module-title">假期列表</div>
        <div class="date-box" id="list-group-item">
          <div class="flex-b box list-group-item" v-for="item in list" :key="item.name">
            <div>{{ item.name }}</div>
            <div class="circle" :class="item.color">{{ item.value }}</div>
          </div>
        </div>

      </el-col>
      <el-col :span="16">
        <FullCalendar ref="fullCalendar" :options="calendarOptions"/>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import { holidayItem, holidayAdd } from '@/api/methodsApi' // 项目中接口文件引入
import * as moment from 'moment'
import '@fullcalendar/core/vdom' // solves problem with Vite
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin, { Draggable } from '@fullcalendar/interaction'
export default {
  name: 'TradingTimeManage',
  components: {
    FullCalendar
  },
  data() {
    return {
      eventEl: null,
      calendarOptions: { //?拖拽日历配置
        plugins: [dayGridPlugin, interactionPlugin],
        firstDay: 1, // 把每周设置为从周一开始
        header: { // 日历头部
          left: 'prev,next today',
          center: 'title',
          right: 'custom'
        },
        /* 设置按钮文字 */
        buttonText:{
          today:'今天',
        },
        initialView: 'dayGridMonth',
        locale: 'zh-cn', //? 配置中文
        selectable: true,//可编辑
        // dayMaxEvents: true,
        slotMinutes: 15,
        editable: false, // 日历上是否可拖拽
        droppable: true,
        dropAccept: '.list-group-item',
        drop: this.drop,
        customButtons: {
          prev: {
            // this overrides the prev button
            text: "PREV",
            click: () => {
              this.prevMethod();
            },
          },
          next: {
            // this overrides the next button
            text: "PREV",
            click: () => {
              this.nextMethod();
            },
          },
          today: {
            text: "今天",
            click: () => {
              this.todayMethod();
            },
          },
        },
        events: []
      },
      start: null,
      end: null,
      calendarEvents: [],
      list: [
        // { name: '删除假日', value: '0', color: 'blue'  }
        { name: '工作日', value: '1', color: 'green' },
        { name: '春节放假', value: '7', color: 'blue' },
        { name: '中秋节放假', value: '3', color: 'blue'  },
        { name: '国庆节放假', value: '7', color: 'blue'  },
        { name: '游玩', value: '7', color: 'blue'  },
      ]
    }
  },
  mounted() {
    var containerEl = document.getElementById('list-group-item');
    // 初始化外部事件
    new Draggable(containerEl, {
        itemSelector: '.list-group-item',
      }
    )
    this.holidayEvent() // 调用获取视图活动数据方法
  },
  methods: {
    /** 上个月  */
    prevMethod() {
      this.$refs.fullCalendar.getApi().prev() // 更新上个月视图
      this.holidayEvent() // 调用获取视图活动数据方法
    },
    /** 下个月  */
    nextMethod() {
      this.$refs.fullCalendar.getApi().next() // 更新下个月视图
      this.holidayEvent() // 调用获取视图活动数据方法
    },
    /** 今天  */
    todayMethod() {
      this.$refs.fullCalendar.getApi().today() // 更新今天视图
      this.holidayEvent() // 调用获取视图活动数据方法
    },
    /** 获取视图活动数据方法 */
    holidayEvent(){
      // 获取当前视图日历的范围
      const time = this.$refs.fullCalendar.getApi().currentDataManager.state.dateProfile.renderRange
      this.start = Date.parse(moment(time.start).format()) // 视图开始时间
      this.end = Date.parse(moment(time.end).format()) // 视图结束时间
      // 从接口获取数据,更新日历视图活动
      holidayItem({ start: this.start, end: this.end }).then((res)=> {
        if (res.status === '200') {
          const data = res.data
          const arr = []
          data.forEach(item => {
             const obj = {
               id: item.id,
               title: item.name,
               start: item.day,
               end: item.dayEnd,
               allDay: true,
               backgroundColor: item.name === '工作日' ? 'green' : '#3788d8'
             }
             arr.push(obj)
           
          })
          this.calendarOptions.events = arr
        }
      })
    },
    drop(date, allDay) {
      let typeNumber = null
      const firstChildName = null
      const obj = {
        name: date.draggedEl.firstChild.innerHTML,
        day:Date.parse(moment(date.dateStr).format()), // 开始时间
        dayEnd:  Date.parse(moment(date.dateStr).add(date.draggedEl.lastChild.innerHTML, 'days').format()), // 结束时间
        dayNum: date.draggedEl.lastChild.innerHTML,
      }
      // 拖拽后,新增日历活动接口调用
      holidayAdd(obj).then(res=>{
        if(res.status === '200') {
          console.log(res, 'data')
          const data = res.data
          this.holidayEvent() // 调用获取视图活动数据方法
        }
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.circle {
  background-color: #3788d8;
  border-radius: 10px;
  color: #fff;
  display: inline-block;
  font-size: 12px;
  height: 18px;
  line-height: 18px;
  padding: 0 6px;
  text-align: center;
  white-space: nowrap;
  border: 1px solid #fff;
}
.blue {
  background-color: #3788d8;
}
.green{
  background-color: green;
}
.date-box {
  //border: 1px solid #ccc;
  border-radius: 5px;
}
.box {
  margin-top:15px;
  border: 1px solid #ccc;
  padding: 10px 20px;
  border-radius: 5px;
}

.is-selected {
  color: #1989FA;
}
</style>

注意:不要在eventsSet: this.handleEvents这个方法中去操作this.calendarOptions.events数据。如果在handleEvents方法中去请求接口,或者赋值,会导致视图一直刷新,进入死循环。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue中使用FullCalendar实现自由拖拽日历活动(包含获取当前视图开始时间与结束时间,动态渲染接口日历活动数据) 的相关文章

随机推荐