> 文章列表 > 第7章 -日历组件 - calendar

第7章 -日历组件 - calendar

第7章 -日历组件 - calendar

日历组件当前并没有基于element-plus封装,而是找的第三方组件库fullcalendar封装的
官方文档:https://fullcalendar.io/demos

1.首先根据需要安装包

npm install @fullcalendar/core @fullcalendar/interaction @fullcalendar/daygrid --save
--components/calendar--src--index.vue--types.ts--index.ts

src/types.ts

export interface EventItem {// 事件标题title: string,// 开始时间start: string,// 结束时间end: string,// 是否可拖动编辑editable?: boolean
}

src/index.vue

<template><div id="calendar"></div>
</template><script lang='ts' setup>
// 在vite里面使用fullcalendar 需要引入一个包
import '@fullcalendar/core/vdom'
import { Calendar, EventClickArg, EventContentArg } from '@fullcalendar/core'
import daygridPlugin from '@fullcalendar/daygrid'
import interactionPlugin , {DateClickArg} from '@fullcalendar/interaction'
import { ref, onMounted, PropType, watch } from 'vue';
import {EventItem} from './types'let props = defineProps({// 日历显示的语言local: {type: String,default: 'zh-cn'},// 视图模式initialView: {type: String,default: 'dayGridMonth'},// 按钮文字buttonText: {type: Object,default: () => {return {today: '今天',month: '月',week: '周',day: '日',prevYear: '上一年',nextYear: '下一年',prev: '上一月',next: '下一月'}}},// 头部工具栏headerToolbar: {type: Object,default: () => {return {start: 'title',center: '',end: 'prev today next'}}},// 底部工具栏footerToolbar: {type: Object},// 日历事件events: {type: Array as PropType<EventItem[]>,default: () => []},// 自定义渲染内容方法eventContent: {type: Function}
})let emits = defineEmits(['date-click', 'event-click'])// 日历对象
let calendar = ref<Calendar>()// 生成日历的方法
let renderCalendar = () => {let el = document.getElementById('calendar')if (el) {// 日历的配置选项calendar.value = new Calendar(el, {// 使用到的插件plugins: [daygridPlugin, interactionPlugin],// 视图模式initialView: props.initialView,// 语言locale: props.local,// 按钮文字buttonText: props.buttonText,// 头部工具栏headerToolbar: props.headerToolbar, // 底部工具栏footerToolbar: props.footerToolbar,// 事件源eventSources: [{// 生成事件events(e, callback) {if (props.events.length) callback(props.events)else callback([])}}],// 点击日历的某一天dateClick(info: DateClickArg) {// console.log(info)emits('date-click', info)},// 点击日历上的时间eventClick(info: EventClickArg) {// console.log('eventClick', info)emits('event-click', info)},// 显示事件的结束时间displayEventEnd: true,// 自定义渲染内容eventContent: props.eventContent})calendar.value.render()}
}// 监听事件源的变化
watch(() => props.events, () => {renderCalendar()
}, {deep: true})
onMounted(() => {renderCalendar()
})
</script><style lang='scss' scoped>
svg {width: 1em;height: 1em;
}
</style>

index.ts

import { App } from 'vue'
import calendar from './src/index.vue'// 让这个组件可以通过use的形式使用
export default {install(app: App) {app.component('m-calendar', calendar)}
}

在项目中使用
views/calendar/index.vue

<template><m-calendar :events="events" :eventContent="eventContent" @date-click="dateClick"></m-calendar>
</template><script lang='ts' setup>
import { DateClickArg } from '_@fullcalendar_interaction@5.10.1@@fullcalendar/interaction';
import { EventItem } from '../../components/calendar/src/types'
import { ref } from 'vue';
import { EventContentArg } from '@fullcalendar/core';let events = ref<EventItem[]>([{title: '购物',start: '2021-11-11 10:00:00',end: '2021-11-11 12:00:00',editable: true},{title: '学习',start: '2021-11-15 08:00:00',end: '2021-11-15 16:00:00'}
])
let dateClick = (info: DateClickArg) => {let event = {start: `${info.dateStr} 12:00:00`,end: `${info.dateStr} 13:00:00`,title: '吃饭'}events.value.push(event)console.log(info)
}let eventContent = (arg: EventContentArg) => {let el = document.createElement('div')let timeTextArr = arg.timeText.split(' - ')let start = timeTextArr[0].replace('上午', '').replace('下午', '').replace('时', '')let end = timeTextArr[1].replace('上午', '').replace('下午', '').replace('时', '')el.innerHTML = `<img src="src/assets/logo.png" style="width:20px;height:20px;"><div>开始时间: ${start}</div><div>结束时间: ${end}</div><div>标题: ${arg.event._def.title}</div>`return {domNodes: [el]}
}
</script><style lang='scss' scoped>
</style>