/**
日历原始数据结构
months: [
['第1周', 1, 2, 3, 4, 5, 6, 7],
['第2周', 8, 9, 10, 11, 12, 13, 14],
['第3周', 15, 16, 17, 18, 19, 20, 21],
],
*/
<template>
<div class="Calendar">
<table class="width100p">
<caption class="lineHeight30" style="color: #2c3e50">{{ formatDate(firstDay) }}</caption>
<tbody>
<tr class="tableClass border1cccccc">
<th class="lineHeight30">教学周</th>
<th class="lineHeight30">星期一</th>
<th class="lineHeight30">星期二</th>
<th class="lineHeight30">星期三</th>
<th class="lineHeight30">星期四</th>
<th class="lineHeight30">星期五</th>
<th class="lineHeight30">星期六</th>
<th class="lineHeight30">星期日</th>
</tr>
<template v-for="(week, index) in calendarData">
<tr :key="'w'+index" class="tableClass border1cccccc">
<td v-for="(atom, index) in week" :key="'d'+index">
<div>{{ atom.label }}</div>
</td>
</tr>
</template>
</tbody>
</table>
<br>
<button @click="doBeforeOneMonth">上一月</button>
<button @click="doAfterOneMonth">下一月</button>
</div>
</template>
<script>
import dayjs from 'dayjs'
export default {
name: 'zydxCalendar', // 组件名称
components: {},
props: [], // 组件参数
model: { // 用于 props 绑定父级 v-model
},
filters: { // 过滤器
},
computed: { // 计算属性
},
watch: { // 监听属性
},
data () {
return {
/*
* 页面状态
* */
/*
* 页面数据
* */
calendarData: [],
firstDay: '2021-1-1'
}
},
methods: {
// 格式化时间
formatDate (date) {
return dayjs(date).format('YYYY年M月')
},
// 上一月
doBeforeOneMonth () {
this.firstDay = this.beforeOneMonth(this.firstDay)
this.getCalendar(this.firstDay)
},
beforeOneMonth (date) {
// date 格式 2021-1-1
return dayjs(date).subtract(1, 'month').format('YYYY-M-D')
},
// 下一月
doAfterOneMonth () {
this.firstDay = this.afterOneMonth(this.firstDay)
this.getCalendar(this.firstDay)
},
afterOneMonth (date) {
// date 格式 2021-1-1
return dayjs(date).add(1, 'month').format('YYYY-M-D')
},
// 渲染日历
getCalendar (firstDay) {
// firstDay 格式 2021-1-1
const day = parseInt(dayjs(firstDay).format('D')) // 获取 日
const yearMonth = dayjs(firstDay).format('YYYY-M')
let firstDayOfWeek = dayjs(firstDay).day() // 当天是星期几
const totalDays = dayjs(firstDay).daysInMonth() // 这个月一共有几天
const remainDays = totalDays - day // 这个月还剩几天
const days = [] // 当前月的所有号
// 生成当月日期数组
let i = -1
while (i < remainDays) {
days.push(day + i + 1)
i++
}
// 月的数组
let finalMonth = []
let sliceStart = 0 // 截取日期的起始
if (firstDayOfWeek === 0) {
firstDayOfWeek = 7
}
let sliceGap = 7 - firstDayOfWeek + 1 // 截取几天
let isArrayEmpty = false // 是否截取不出来了的标记
let sliceTimes = 0
while (!isArrayEmpty) {
let weekTip = [] // 日历中每一条的数据
if (sliceTimes === 0) { // 首次截取
let weekTipAfter = days.slice(sliceStart, sliceGap)
if (weekTipAfter.length < 7) {
for (let i = 0; i < 7 - weekTipAfter.length; i++) { // 添加前面的空白
weekTip.push('')
}
}
weekTip = weekTip.concat(weekTipAfter)
} else { // 再次截取
weekTip = days.slice(sliceGap, sliceGap + 7)
sliceGap = sliceGap + 7
// 尾部添 空白
let trailAppend = 7 - weekTip.length
if (trailAppend < 7 && trailAppend > 0) {
for (let j = 0; j < trailAppend; j++) {
weekTip.push('')
}
}
trailAppend = 0
}
sliceTimes++
// 如果截取不出来了则 跳出循环
if (weekTip.length !== 0) {
finalMonth.push(weekTip)
} else {
isArrayEmpty = true
}
}
// 添加教学周
finalMonth.map((item, index) => {
item.splice(0, 0, `第 ${index + 1} 周`)
})
// 更换数据结构
let calendarData = []
finalMonth.map((item) => {
let calendarPart = []
item.map((atom) => {
if (typeof (atom) === 'number') {
calendarPart.push({
label: atom,
date: yearMonth + '-' + atom,
remarks: [] // 此处可以放一些数据
})
} else {
calendarPart.push({
label: atom
})
}
})
calendarData.push(calendarPart)
})
// 调试输出
// console.log(day + '日当天是星期几', firstDayOfWeek)
// console.log('这个月一共有几天: ', totalDays)
// console.log('这个月还剩几天: ', remainDays)
// console.log('days数组', days)
// console.log('获得最终日历', finalMonth)
// console.log('日历数据结构调整', calendarData)
// 结束
this.calendarData = calendarData
}
},
beforeCreate () { // 播放加载动画
},
created () { // 结束加载动画, 发起异步请求
},
mounted () { // DOM构建完成, 即将显示页面
this.getCalendar(this.firstDay)
},
updated () { // view重新渲染, 数据更新
},
beforeDestroy () { // 组件实例销毁之前
}
}
</script>
<style scoped>
.lineHeight30 {
line-height: 30px;
}
caption {
padding: 0 0 0 30px;
border: 1px #cccccc solid;
border-bottom: none;
}
.tableClass th {
border: 1px #cccccc solid;
font-size: 14px;
}
.tableClass td {
border: 1px #cccccc solid;
font-size: 14px;
}
</style>
基于 Dayjs 与 Vue2 的简易日历
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
推荐阅读更多精彩内容
- 效果: 最近项目种需要用到工作日历,之前写过JQ版本的GitHub,直接把JQ版本换成Vue,SMCalendar...
- 今天闲着无聊写了个关于日历的组件玩玩,在这里记录一下实现方式。做一个简单的日历组件,只需要一个Date对象就可以完...
- 项目介绍:制作一个网赚应用平台:ios手机技术选型:vue + vuex + vue-router + vue-r...