日历组件
先看效果图,如下:在线预览
背景介绍:pc端需求,做一个日历组件,可以在上面添加日程。当然这里业务功能部分就没有写,大家只可参考日历的实现即可。
核心代码介绍
根据vue
的核心思想:数据驱动来生成所需要的数据,实现页面的自动渲染及更新。
- 组装日期核心对象
calendarData
看到这个图,第一个想到的是要生成每个月的所有天数,然后还有各个状态:
即默认当天日期(图中默认蓝色数字)、选中日期(点击背景蓝色)、不可选的日期(灰色字体)及(有日程的等)及样式。
- 生成日期对象:
// 初始化日历
// isClickToday参数只是为了处理点击“今天”的判断
initCalendar(isClickToday = false) {
const nowDate = new Date()
this.viewDate(nowDate, isClickToday)
},
// 初始化日期控件
viewDate(nowDate, isClickToday = false) {
this.currentShowDate = Utility.formatDate(nowDate, 'yyyyMMdd')
const year = nowDate.getFullYear()
const month = nowDate.getMonth() + 1
const currentDate = nowDate.getDate()
this.currentYear = year
this.currentMonth = month
let dayNum = 0 // 当前月有多少天
if (month === 1 || month === 3 || month === 5 || month === 7 || month === 8 || month === 10 || month === 12) {
dayNum = 31
} else if (month === 4 || month === 6 || month === 9 || month === 11) {
dayNum = 30
} else if (month === 2 && this.isLeapYear(year)) { // 如果是闰年,2月有29天
dayNum = 29
} else {
dayNum = 28
}
this.calendarData = []
var _firstDay = new Date(year, month - 1, 1) // 当前月第一天
for (var i = 0; i < 42; i++) {
let day = i + 1 - _firstDay.getDay() // 根据周几计算
let _thisDate = new Date(year, month - 1, day)
let _thisMonth = _thisDate.getMonth() + 1
let _thisDay = _thisDate.getDate()
let _currentDate = Utility.formatDate(_thisDate, 'yyyy-MM-dd')
let curentDay = {
isCurrentMonth: _thisMonth === month, // 是否是当月时间,只有当月才可以点击和移动变色
isCurrentDay: _thisDay === currentDate, // 是否是当月的当天
isClick: false,
value: _thisDay,
month: _thisMonth,
longStrDate: _currentDate.replace(/-/g, ''),
currentDate: _currentDate,
isHasData: false // 是否存在数据(处理业务逻辑时用)
}
this.calendarData.push(curentDay)
}
if (isClickToday) {
let item = this.calendarData.find(d => d.isCurrentDay)
this.$emit('changeDate', item.currentDate)
}
},
// 判断是否为闰年
isLeapYear(year) {
if ((year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0)) {
return true
} else {
return false
}
},
// 切换日期
changeMonth(type) {
let nowDate = new Date()
let month = this.currentMonth
if (type === 0) {
month = this.currentMonth - 1
} else {
month = this.currentMonth + 1
}
nowDate.setFullYear(this.currentYear)
nowDate.setMonth(month - 1)
nowDate.setDate(nowDate.getDate())
console.log('切换日期', nowDate)
this.viewDate(nowDate)
// 回调方法
this.$emit('changeDate', Utility.formatDate(nowDate, 'yyyy-MM-dd'))
},
// 选中哪一天
checkDate(item) {
if (!item.isCurrentMonth) return
this.calendarData.forEach(d => {
// && !item.isCurrentDay 如果当天就不选中
d.isClick = d.value === item.value && d.month === item.month
})
// 回调方法
this.$emit('checkDay', item)
},
// 赋值具体日期
checkDays(date) {
this.viewDate(new Date(date))
}
- 组件的使用:/views/calendar.vue
<cale-comp ref="calendar" @changeDate="changeDate" @checkDay="checkDay"></cale-comp>
详细代码可参考这里.