行业知识
前端之vue 封装自定义日历
2026-11-13 02:20:26
来源:互联网转载
关于自定义日历
工作需要,现有框架封装的日历无法满足需求,又找不到更好的插件的情况下,咋办??自己写个呗!
效果图和功能说明
先看看效果图
在这里插入图片描述
其实基本界面就这样了,和其他没啥区别。
但是既然要单独封装一个,那肯定有其他可扩展的地方,不然就没意义了
功能说明
1、基本日历功能
2、可以自定义标题头部
3、可自定义顶部时间以及月份切换部分
4、日历单元格样式可以自定义
5、星期一栏可以自定义
6、可以在日历里面插入数据:这一点是最重要的,也是必须要自己封装的重要因素
使用
封装为日历组件,直接引用即可。需要扩展其他功能,可以看组件里面的props哦,这是可以接收的参数。当然,如果用props不能满足的,那就看看里面的slot插槽部分咯。
这是props定义接收的参数,每个参数均有注释,这里不多做介绍。
props: { initDate:{ type:[String,Date,Number], default:()=>new Date() },//初始化日期 width:{ type:[String,Number], default:'100%' },//日历宽度 height:{ type:[String,Number], default:'100%' },//日历高度 calendarClass:String,//日历自定义样式类 titleClass:String,//年月标题自定义样式类 titleH:{ type:[String,Number], default:'35px' },//年月标题高度 titleBk:{ type:String, default:'#ffffff' },//年月标题颜色 bodyBk:{ type:String, default:'#ffffff' },//日历体背景 bodyClass:String,//日历体自定义样式 dateDefaultClass:String,//日期自定义默认类名 dateActivDateClass:String,//日期自定义选中类名 dateDisabledDateClass:String,//日期自定义不可见类名 titleDateConnector:String,//标题日期连接符 insertData:{ type:Array, default:()=>[] },//自定义拼接数据 weeks:{ type:Array, default:()=>['日','一','二','三','四','五','六'] },//周数据 dateProp:{ type:String, default:'date' },//自定义表示时间的字段 calenCellClass:String,//日历单元格自定义样式 firstRowCellClass:String,//日历第一行单元格自定义样式 firstColumCellClass:String,//日历第一列单元格自定义样式 cellBorder:Boolean,//是否有边框 cellTitleHeight:{ type:[Number,String], default:'40px' },//日历标题高度 cellTitleColor:{ type:String, default:'#333333' },//日历标题颜色 range:{ type:Array, default:()=>[] },//日期范围 }, 更多个性化功能请看slot部分
在这里插入图片描述
插槽使用示例:
不熟悉插槽的伙伴可以去vue官网补补:https://cn.vuejs.org/v2/guide/components-slots.html
日历标题 {{currentYear}}年{{currentMonth}}月 返回今天 其他不多说了,最后上代码。由于组件代码放在一个页面写重了点,因此分成了几个文件
所有data里面的变量,props,还有函数均有说明。
先看canlendar.vue
{{currentYear}}{{titleDateConnector || '年'}}{{currentMonth+1}}{{titleDateConnector ? '' : '月'}} < > {{week}} {{day.day}} import {isValidDate,isNumber} from "./validate" import {getStartTimeEndTimeInfoFun,insertDataToCalendar} from './util' export default { name: "Calendar", props: { initDate:{ type:[String,Date,Number], default:()=>new Date() },//初始化日期 width:{ type:[String,Number], default:'100%' },//日历宽度 height:{ type:[String,Number], default:'100%' },//日历高度 calendarClass:String,//日历自定义样式类 titleClass:String,//年月标题自定义样式类 titleH:{ type:[String,Number], default:'35px' },//年月标题高度 titleBk:{ type:String, default:'#ffffff' },//年月标题颜色 bodyBk:{ type:String, default:'#ffffff' },//日历体背景 bodyClass:String,//日历体自定义样式 dateDefaultClass:String,//日期自定义默认类名 dateActivDateClass:String,//日期自定义选中类名 dateDisabledDateClass:String,//日期自定义不可见类名 titleDateConnector:String,//标题日期连接符 insertData:{ type:Array, default:()=>[] },//自定义拼接数据 weeks:{ type:Array, default:()=>['日','一','二','三','四','五','六'] },//周数据 dateProp:{ type:String, default:'date' },//自定义表示时间的字段 calenCellClass:String,//日历单元格自定义样式 firstRowCellClass:String,//日历第一行单元格自定义样式 firstColumCellClass:String,//日历第一列单元格自定义样式 cellBorder:Boolean,//是否有边框 cellTitleHeight:{ type:[Number,String], default:'40px' },//日历标题高度 cellTitleColor:{ type:String, default:'#333333' },//日历标题颜色 range:{ type:Array, default:()=>[] },//日期范围 }, data() { return { calendarList: [],//日历数据 activeDay: {},//选中日期信息 currentYear: '',//显示的年 currentMonth: '',//显示的月 chooseDate: '',//选择的日期 calenCellHeight:0,//日历单元格高度 calenBotyTitleCellStyle:{},//日历顶部单元格样式 calenCellStyle:{},//日历单元格样式 calendarWidth:'100%',//日历宽度 calendarHeight:'100%',//日历高度 titleHeight:'35px',//年月标题高度 dateCellDefaultClass:'',//日历单元格默认类名 dateCellActiClass:'',//日历单元格选中类名 dateCellDisabledClass:'',//日历不可见单元格类名 cellBorderStyle:(index)=>{return {}},//日历单元格边框样式 bodyCellTitleHeight:'40px' } }, async created(){ console.log(this.calenCellClass) let {width,height,titleH,dateDefaultClass,dateActivDateClass,dateDisabledDateClass,cellTitleHeight}=this this.calendarWidth=(typeof width==='number' || isNumber(width)) ? (width+'px') : width this.calendarHeight=(typeof height==='number' || isNumber(height)) ? (height+'px') : height this.titleHeight=(typeof cellTitleHeight==='number' || isNumber(cellTitleHeight)) ? (cellTitleHeight+'px') : cellTitleHeight this.bodyCellTitleHeight=(typeof titleH==='number' || isNumber(titleH)) ? (titleH+'px') : titleH this.dateCellDefaultClass=dateDefaultClass || 'dateDefaultCss' this.dateCellActiClass=dateActivDateClass || 'dateActiveCss' this.dateCellDisabledClass=dateDisabledDateClass || 'disableDateCss' let {dateTime,isValid}=isValidDate(this.initDate) if(!isValid) return let year=dateTime.getFullYear() let month=dateTime.getMonth() let date=dateTime.getDate() await this.init(year,month,date) insertDataToCalendar(this.insertData,this.calendarList,this.dateProp) }, methods: { //初始化日历 async init(year, month, date,config={}) { this.currentYear = year this.currentMonth = month let daysInMonth = new Date(year, month+1,0).getDate()//得到当前月份的天数 28,29,30,31 let firstDayInWeek = new Date(year, month,1).getDay()//获取当月的一号是星期几 let lastDayInWeek = new Date(year,month,daysInMonth).getDay()//获取当月最后一天是星期几 this.calendarList = await this.createcalendarList(year, month, date, firstDayInWeek, lastDayInWeek, daysInMonth,config) return this.calendarList }, //创建日历 createcalendarList(year, month, date, firstDayInWeek, lastDayInWeek, daysInMonth,config={}) { return new Promise((resolve)=>{ let thisYear=new Date().getFullYear() let thisMonth=new Date().getMonth() if(thisYear===year && thisMonth===month){ date=new Date().getDate() } let {isChangeMonth}=config let { calenStartDate,calenEndDate,calenStartYear,calenStartMonth,dateRangeCode}=getStartTimeEndTimeInfoFun(this.range[0],this.range[1]) // console.log(calenStartDate,calenEndDate,dateRangeCode,calenStartMonth) if(!isChangeMonth && dateRangeCode){ //日期范围有效 this.currentYear = calenStartYear this.currentMonth = calenStartMonth } let calendarList = [] //1号不在星期天,补全前面的日期信息 // console.log(firstDayInWeek) if (firstDayInWeek !== 0) { let prevMonthLastDate=new Date(year,month,0).getDate() for (let j = firstDayInWeek-1; j >= 0; j--) { calendarList.push({ dateClass: this.dateCellDisabledClass, year, month, day: prevMonthLastDate - j, week: new Date(year,month-1,prevMonthLastDate - j).getDay(), isThis: false }) } } // 添加日期信息 for (let i = 0; i
上一篇:苹果怎么代理服务器?