封装组件库-日历
2023, Mar 13
实现日历的封装
基于FullCalendar插件进行封装。
初始配置
- 注册路由组件calendar,配置为Container组件的子路由组件
- 采用路由懒加载,箭头函数异步引入组件。
- 注册通用组件calendar,为路由组件的子组件,以便组件间通信。
- 将通用组件calendar注册为全局组件
配置基础日历
- 子组件props配置:
let props = defineProps({
//语言
locale:{
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,
default: ()=>{}
},
//显示事件的结束时间
displayEventEnd:{
type: Boolean,
default: false
},
})
- 子组件渲染日历
let renderCalendar = ()=>{
let el = document.getElementById('calendar')
if(el){
calendar.value = new Calendar(el,{
// 日历插件
plugins:[daygrid,interaction],
locale: props.locale,
initialView: props.initialView,
buttonText: props.buttonText,
headerToolbar: props.headerToolbar,
footerToolbar: props.footerToolbar,
displayEventEnd: props.displayEventEnd
}
实现事件功能
- 定义事件类型接口
export interface EventItem {
//事件标题
title: string,
//开始时间
start: string,
//结束时间
end: string,
//是否可拖拽
editable?: boolean
}
- 子组件:props配置项添加。
let props = defineProps({
//事件源
events:{
type: Array as PropType<EventItem[]>,
default:()=>[]
}
})
- 在构造函数配置项添加事件源配置:判断events是否为空,callback进行渲染
eventSources: [
{
//渲染日历事件
events(e,callback){
if(props.events.length) callback(props.events)
else callback([])
}
}
],
- 父组件传递events数据:通过添加editable实现可拖拽的功能。
let events = ref<EventItem[]>([
{
title: '购物',
start: '2023-03-11 08:00',
end: '2023-03-11 12:00',
editable: true
},
{
title: '敲代码',
start: '2023-03-14 10:00',
end: '2023-03-14 16:00'
}
])
- 实现点击日期添加自定义事件:FullCalendar有dateClick、eventClick方法可通过点击具体实例获取日期和事件。通过分发事件发送给父组件,父组件向events里添加事件。
- 子组件监听events的变化,调用渲染日历的方法重新渲染.
dateClick(info: DateClickArg){
emits('dateClick',info)
},
eventClick(info: EventClickArg){
emits('eventClick',info)
}
<!-- 父组件向events里添加事件 -->
let dataClick = (info: DateClickArg)=>{
events.value.push({
start: info.dateStr + ' 12:00',
end: info.dateStr + ' 18:00',
title: '学习'
})
}
//监听父组件传递的事件源
watch(()=>props.events,val=>{
renderCalendar()
},{deep:true})
实现自定义事件渲染
- 父组件传递方法eventContent(为FullCalendar配置项)
- 创建el实例,timeText为事件的具体时间,拿到开始和结束时间,通过innerHTML定义样式,return 传入domNodes的数组实现自定义渲染。
let eventContent = (arg: EventContentArg)=>{
let el = document.createElement('div')
let timeTextArr = arg.timeText.split('-')
let start = timeTextArr[0].replace('上午','').replace('时',':00')
let end = timeTextArr[1].replace('下午','').replace('时',':00')
el.innerHTML = `
<div>开始时间: ${start}</div>
<div>结束时间: ${end}</div>
<div>标题: ${arg.event._def.title}</div>
`
return {
domNodes:[el]
}
}