日历组件当前并没有基于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>