vue3使用fullcalendar 日历插件,基础使用!

官网链接:FullCalendar - JavaScript Event Calendar

本文中是基于VUE3+elementui-plus项目中实现的前后端分离的前端功能部分:

一、安装组件

pnpm install @fullcalendar/core --save 
pnpm install @fullcalendar/vue3 --save
pnpm install @fullcalendar/daygrid --save
pnpm install @fullcalendar/interaction--save
pnpm install @fullcalendar/timegrid --save
pnpm install @fullcalendar/resource-timeline  --save

1.放置组件展示的div 

<template>
  <div class="app-container meetingroomApply">
    <!--按钮添加内容开启自定义弹窗-->
    <el-button
      type="primary"
      size=" medium"
      @click="openDialog"
      style="margin-bottom: 10px"
      >会议室预定</el-button
    >
    <div class="fullCalendar" id="calendar"></div>
  </div>
</template>

2.对应的js代码

<script setup>
import FullCalendar from '@fullcalendar/vue3'
import { Calendar } from '@fullcalendar/core'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin from '@fullcalendar/interaction'
import timeGridPlugin from '@fullcalendar/timegrid'
import resourceTimelinePlugin from '@fullcalendar/resource-timeline'
const FullCalendarRef = ref(null)
const calendar = ref(null)
const showSearch = ref(true)
const buttonLoading = ref(false)
const title = ref('')
const deptOptions = ref([])
const deptOptionsLink = ref([])
const companyList = ref([])
const meetingroomList = ref([])
const meetingroomEventList = ref([])
const form = ref({
  meetingName: '',
  participant: '',
  projectionScreen: '',
  tableBrand: '',
  bottleWater: '',
  otherNeeds: '',
  remark: '',
  meetingStartTime: '',
  meetingEndTime: '',
  meetingroomName: '',
  meetingroomId: ''
})
const rules = ref({})
const queryParams = ref({
  meetingroomNo: undefined,
  meetingroomName: undefined,
  meetingDay: undefined,
  viewType: undefined,
  beginDayTime: undefined,
  endDayTime: undefined,
  year: undefined,
  month: undefined
})

//监听到的当前view模式
const viewType = ref('')
const calendarOptions = ref({
  height: 800,
  allDaySlot: false,
  axisFormat: 'h(:mm)tt',
  plugins: [dayGridPlugin, interactionPlugin, timeGridPlugin, resourceTimelinePlugin],
  locale: 'zh-cn', // 中文
  initialView: 'resourceTimelineDay',
  headerToolbar: {
    left: 'prev,next today',
    center: 'title',
    right: 'resourceTimelineDay,resourceTimelineWeek,dayGridMonth'
  },

  buttonText: {
    today: '今天',
    day: '日',
    week: '周',
    month: '月'
  },
  editable: true,
  selectable: true,
  navLinks: true,
  datesSet: (info) => {
    datesSet(info)
  },
  dateClick: (arg) => {
    handleDateClick(arg)
  },
  eventClick: (calEvent) => {
    handleEventClick(calEvent)
  },
  select: (info) => {
    handleSelect(info)
  },
  resourceAreaColumns: [
    {
      headerContent: '会议室'
    }
  ],
  eventColor: '#f08f00',
  locale: 'zh-cn',
  weekNumberCalculation: 'ISO',
  customButtons: {
    prev: {
      text: '前一天',
      click: () => {
        prev()
      }
    },
    next: {
      text: '后一天',
      click: () => {
        next()
      }
    },
    today: {
      text: '今天',
      click: () => {
        today()
      }
    }
  },
  slotMinTime: '00:00:00',
  slotMaxTime: '23:59:00',
  resourceAreaWidth: '15%',
  schedulerLicenseKey: 'CC-Attribution-NonCommercial-NoDerivatives'
})

onMounted(() => {
  initCalendar()
  getList()
})
//加载会议事件
const initCalendar = () => {
  var calendarEl = document.getElementById('calendar')
  calendar.value = new Calendar(calendarEl, calendarOptions.value)
  calendar.value.render()
}
const getList = () => {
  queryParams.value.companyIds = 1319
  queryParams.value.viewType = 'day'
  queryParams.value.meetingDay = setCurrentDate(new Date())
  getListApplyMeetingroom(queryParams.value)
}
///获取当前的年月日,做查询参数
const setCurrentDate = (data) => {
  const currentDate = data
  const year = currentDate.getFullYear()
  const month = String(currentDate.getMonth() + 1).padStart(2, '0')
  const day = String(currentDate.getDate()).padStart(2, '0')
  const formattedDate = `${year}-${month}-${day}`
  return formattedDate
}
const getListApplyMeetingroom = (queryParams) => {
  nextTick(() => {
    // listApplyMeetingroom(queryParams).then((response) => {}); //修改为自己的接口

    //清空原始数据
    meetingroomList.value = [
      {
        id: 1,
        companyId: 1319,
        companyName: '测试',
        companyShortName: null,
        tenantId: 1319,
        meetingroomNo: 'HYS20241118001',
        meetingroomName: '测试 - 500会议室',
        meetingroomLocation: '测试公司三层309会议室',
        meetingroomArea: '86.0000',
        meetingroomGalleryful: 40,
        meetingroomEquipment: '投影仪',
        appliable: 1,
        remark: '第一次申请',
        scopeDeptId: 1321,
        projectionScreen: null,
        tableBrand: null,
        bottleWater: null
      },
       {
        id: 2,
        companyId: 1319,
        companyName: '测试',
        companyShortName: null,
        tenantId: 1319,
        meetingroomNo: 'HYS20241118001',
        meetingroomName: '测试 - 500会议室',
        meetingroomLocation: '测试公司三层309会议室',
        meetingroomArea: '86.0000',
        meetingroomGalleryful: 40,
        meetingroomEquipment: '投影仪',
        appliable: 1,
        remark: '第一次申请',
        scopeDeptId: 1321,
        projectionScreen: null,
        tableBrand: null,
        bottleWater: null
      }
    ]
    meetingroomEventList.value = [
      {
        id: 20,
        meetingroomId: 1,
        meetingroomName: '测试 - 309会议室',
        meetingName: '22好的会议',
        participant: '我额人他',
        meetingStartTime: '2025-01-16 09:30:00',
        meetingEndTime: '2025-01-16 13:30:00',
        specialRequest: null,
        companyId: 1319,
        companyName: '测试公司',
        userCode: '1',
        userName: 'sysadmin',
        userPhone: '1222222222',
        deptId: 1323,
        deptName: '研发部',
        applyTime: null,
        applyStatus: 1,
        cancelRemark: null,
        remark: '问问嗯嗯',
        tenantId: 1319,
        scopeDeptId: 1323,
        projectionScreen: 1,
        tableBrand: 1,
        bottleWater: 1,
        otherNeeds: '问问'
      },
      {
        id: 20,
        meetingroomId: 1,
        meetingroomName: '测试 - 309会议室',
        meetingName: '22好的会议',
        participant: '我额人他',
        meetingStartTime: '2025-01-16 10:30:00',
        meetingEndTime: '2025-01-16 15:30:00',
        specialRequest: null,
        companyId: 1319,
        companyName: '测试公司',
        userCode: '1',
        userName: 'sysadmin',
        userPhone: '1222222222',
        deptId: 1323,
        deptName: '研发部',
        applyTime: null,
        applyStatus: 1,
        cancelRemark: null,
        remark: '问问嗯嗯',
        tenantId: 1319,
        scopeDeptId: 1323,
        projectionScreen: 1,
        tableBrand: 1,
        bottleWater: 1,
        otherNeeds: '问问'
      }
    ]

    // 提取所有资源的 id 值
    const resourceIds = calendar.value.getResources().map((resource) => resource.id)
    // 逐个删除原有资源,防止显示出错
    resourceIds.forEach((id) => {
      calendar.value.getResourceById(id).remove()
    })

    if (meetingroomList.value.length > 0) {
      // 遍历 this.meetingroomList 并添加资源
      meetingroomList.value.forEach((room) => {
        calendar.value.addResource({
          id: room.id,
          title: room.meetingroomName
        })
      })
    }

    if (meetingroomEventList.value.length > 0) {
      // 获取现有的事件列表
      const existingEvents = calendar.value.getEvents()
      // 添加新的事件,避免重复
      meetingroomEventList.value.forEach((event) => {
        const isDuplicate = existingEvents.some((existingEvent) => {
          const formattedStart = formmatTime(existingEvent.start)
          const formattedEnd = formmatTime(existingEvent.end)

          return (
            formattedStart === formmatTime(event.meetingStartTime) &&
            formattedEnd === formmatTime(event.meetingEndTime)
          )
        })

        if (!isDuplicate) {
          calendar.value.addEvent({
            resourceId: event.meetingroomId,
            title: `${event.meetingName}  预定人: (${event.userName})`,
            start: event.meetingStartTime,
            end: event.meetingEndTime,
            extendedProps: {
              meetingroomId: event.meetingroomId,
              meetingroomName: event.meetingroomName,
              meetingStartTime: event.meetingStartTime,
              meetingEndTime: event.meetingEndTime,
              meetingName: event.meetingName,
              userName: event.userName,
              userPhone: event.userPhone,
              companyName: event.companyName,
              deptName: event.deptName,
              participant: event.participant,
              projectionScreen: event.projectionScreen,
              tableBrand: event.tableBrand,
              bottleWater: event.bottleWater,
              otherNeeds: event.otherNeeds,
              remark: event.remark
            }
          })
        }
      })
    }
  })
}
//添加自定义添加弹出框
const openDialog = () => {
  
  
}
const roomChange = (value) => {
  // 根据选中的会议室名称找到对应的会议室对象
  const selectedRoom = meetingroomList.value.find((room) => room.meetingroomName === value)
  if (selectedRoom) {
    // 更新 form.meetingroomId 为选中的会议室meetingroomNo
    form.value.meetingroomId = selectedRoom.id
  }
}
//选择会议室和时间
const handleSelect = (info) => {
  form.value.meetingStartTime = handleSelectDate(info.startStr)
  form.value.meetingEndTime = handleSelectDate(info.endStr)
  if (info.resource) {
    form.value.meetingroomName = info.resource.title
    form.value.meetingroomId = info.resource.id
  }
}
const handleSelectDate = (selectData) => {
  const originalTime = selectData
  const date = new Date(originalTime)
  const year = date.getFullYear()
  const month = String(date.getMonth() + 1).padStart(2, '0')
  const day = String(date.getDate()).padStart(2, '0')
  const hours = String(date.getHours()).padStart(2, '0')
  const minutes = String(date.getMinutes()).padStart(2, '0')
  const formattedTime = `${year}-${month}-${day} ${hours}:${minutes}:00`
  return formattedTime
}

//获取视图的日期参数
const getViewDate = () => {
  const currentDate = Calendar.getDate()
  const currentViewType = Calendar.view.type

  if (currentViewType === 'resourceTimelineDay') {
    // 日视图
    queryParams.value.viewType = 'day'
    queryParams.value.meetingDay = formatDate(currentDate, 'yyyy-MM-dd')
  } else if (currentViewType === 'resourceTimelineWeek') {
    // 周视图
    const startOfWeek = new Date(currentDate)
    startOfWeek.setDate(startOfWeek.getDate() - startOfWeek.getDay() + 1)
    const endOfWeek = new Date(startOfWeek)
    endOfWeek.setDate(endOfWeek.getDate() + 6)
    queryParams.value.viewType = 'week'
    queryParams.value.beginDayTime = formatDate(startOfWeek, 'yyyy-MM-dd')
    queryParams.value.endDayTime = formatDate(endOfWeek, 'yyyy-MM-dd')
  } else if (currentViewType === 'dayGridMonth') {
    // 月视图

    const startOfMonth = new Date(currentDate)
    startOfMonth.setDate(1)
    const endOfMonth = new Date(currentDate)
    endOfMonth.setMonth(endOfMonth.getMonth() + 1)
    endOfMonth.setDate(0)
    queryParams.value.viewType = 'month'
    queryParams.value.beginDayTime = formatDate(startOfMonth, 'yyyy-MM-dd')
    queryParams.value.endDayTime = formatDate(endOfMonth, 'yyyy-MM-dd')
  }
  queryParams.value.companyIds =
    queryParams.value.tenantIdList.length > 0
      ? queryParams.value.tenantIdList.join(',')
      : form.value.companyId
}
// 辅助方法:格式化日期
const formatDate = (date, format) => {
  const pad = (n) => (n < 10 ? '0' + n : n)
  return format
    .replace('yyyy', date.getFullYear())
    .replace('MM', pad(date.getMonth() + 1))
    .replace('dd', pad(date.getDate()))
}
const prev = () => {
  calendar.value.prev()
  getViewDate()
  getListApplyMeetingroom(queryParams.value)
}
// 切换下一个按钮事件
const next = () => {
  calendar.value.next()
  getViewDate()
  getListApplyMeetingroom(queryParams.value)
}
// 点击今天按钮
const today = () => {
  calendar.value.today()
  getViewDate()
  getListApplyMeetingroom(queryParams.value)
}
const handleDateClick = (arg) => {
  console.log(arg, '事件1')
}
const handleEventClick = (calEvent) => {
  console.log(calEvent, '事件2')
  title.value = '查看会议详情'
  // 将 extendedProps 里的字段及数值逐个放入 this.form
  const extendedProps = calEvent.event.extendedProps
  for (const key in extendedProps) {
    if (extendedProps.hasOwnProperty(key)) {
      form.value[key] = extendedProps[key]
    }
  }
}
const getShowTime = (beginDate, endDate) => {
  form.value.startDate = dealWithTime(beginDate)
  form.value.startTime = getHoursMin(beginDate)
  form.value.endDate = dealWithTime(endDate)
  form.value.endTime = getHoursMin(endDate)
}
// 获取时分时间
const getHoursMin = (value) => {
  return value.substring(11, 16)
}
// 处理会议时间格式
const dealWithTime = (date) => {
  let newDate = /\d{4}-\d{1,2}-\d{1,2}/g.exec(date)[0]
  return newDate
}
const handleEvents = (events) => {
  console.log(events, '事件3')
}

//UTC时间去掉T
const formmatTime = (time) => {
  const utcTimestamp = time
  const date = new Date(utcTimestamp)

  const year = date.getUTCFullYear()
  const month = String(date.getUTCMonth() + 1).padStart(2, '0')
  const day = String(date.getUTCDate()).padStart(2, '0')

  const hours = String(date.getUTCHours()).padStart(2, '0')
  const minutes = String(date.getUTCMinutes()).padStart(2, '0')
  const seconds = String(date.getUTCSeconds()).padStart(2, '0')

  const formattedDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`

  return formattedDateTime
}
const datesSet = (info) => {
  //注意:该方法在页面初始化时就会触发一次
  viewType.value = info.view.type
}

</script>
<style lang="scss">
::v-deep .el-select {
  width: 100%;
}
::v-deep .el-date-editor.el-input,
.el-date-editor.el-input__inner {
  width: 100%;
}
.fc-icon-chevron-right::before {
  content: '>' !important;
}

.fc-icon-chevron-left::before {
  content: '<' !important;
}
</style>

Vue3 和 Tailwindcss 都是现代化的前端技术,它们的结合可以让开发者更加高效地开发出优雅、精美的 UI 界面。下面是一份保姆级教程,帮助您快速上手 Vue3 和 Tailwindcss。 ## 1. 安装 Vue3使用 Vue3 之前,我们需要先安装 Vue3。 可以通过以下命令来安装最新版本的 Vue3: ```bash npm install vue@next ``` ## 2. 创建 Vue3 项目 在安装完 Vue3 之后,我们需要通过 Vue3 CLI 创建一个新的项目。在命令行中输入以下命令: ```bash vue create my-project ``` 这个命令将创建一个名为 `my-project` 的新项目,并自动安装所需的依赖项。 ## 3. 安装 Tailwindcss 接下来,我们需要安装 Tailwindcss。可以通过以下命令安装: ```bash npm install tailwindcss ``` ## 4. 配置 Tailwindcss 安装好 Tailwindcss 之后,我们需要进行一些配置才能在 Vue3 项目中使用。 首先,我们需要在项目的根目录下创建一个 `tailwind.config.js` 文件,用于配置 Tailwindcss。可以使用以下命令创建: ```bash npx tailwindcss init ``` 然后,打开 `tailwind.config.js` 文件,找到并修改以下配置: ```js module.exports = { purge: [], darkMode: false, // or &#39;media&#39; or &#39;class&#39; theme: { extend: {}, }, variants: {}, plugins: [], } ``` 将 `purge` 字段设置为 `[&#39;./src/**/*.{js,jsx,ts,tsx,vue}&#39;]`,用于在构建时删除未使用的样式。这个配置可以有效减小最终构建的文件大小。 ```js module.exports = { purge: [&#39;./src/**/*.{js,jsx,ts,tsx,vue}&#39;], darkMode: false, // or &#39;media&#39; or &#39;class&#39; theme: { extend: {}, }, variants: {}, plugins: [], } ``` ## 5. 集成 Tailwindcss 到 Vue3 项目中 接下来,我们需要将 Tailwindcss 集成到 Vue3 项目中。 打开 `main.js` 文件,添加以下代码: ```js import { createApp } from &#39;vue&#39; import App from &#39;./App.vue&#39; import &#39;./index.css&#39; createApp(App).mount(&#39;#app&#39;) ``` 这段代码将 `index.css` 文件导入到 Vue3 项目中。 然后,我们需要在 `index.css` 文件中导入 Tailwindcss 样式。可以使用以下命令将样式导入到 `index.css` 文件中: ```bash npx tailwindcss-cli@latest build -o ./src/index.css ``` 这个命令将会在 `./src/index.css` 文件中生成所有的 Tailwindcss 样式。 最后,我们需要在 `App.vue` 文件中使用 Tailwindcss 样式。打开 `App.vue` 文件,修改 `<template>` 标签中的内容: ```html <template> <div class="bg-gray-100 p-4"> <h1 class="text-2xl font-bold mb-4">Hello World!</h1> <p class="text-gray-600">This is a Vue3 project with Tailwindcss.</p> </div> </template> ``` 这个修改将会在页面中显示一个灰色背景,一个标题和一段文字。 ## 6. 运行 Vue3 项目 现在,我们已经完成了 Vue3 和 Tailwindcss 的集成。可以通过以下命令来启动 Vue3 项目: ```bash npm run serve ``` 然后打开浏览器,访问 `http://localhost:8080/`,就可以看到页面中显示的内容了。 至此,我们已经完成了 Vue3 和 Tailwindcss 的集成。希望这份保姆级教程能够帮助您快速上手 Vue3 和 Tailwindcss。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值