vue 日历翻拍效果_vue简单日历的实现方案(改造)

本文介绍了如何将CodePen上的日历翻页效果迁移到Vue项目中。通过理解原项目的日历逻辑,将DOM操作转化为Vue的模板操作,创建一个包含日期、是否为今日和是否为本月的数据结构,实现日历的渲染。文章详细讲解了核心代码的逻辑转换,并提供了关键代码示例。
摘要由CSDN通过智能技术生成

改造项目

场景

自己写个聚合首页,方便自己统一管理常用的网页工具,参考的是Mac OS的仪表盘,如下:

虽然短时间没法做到这么精美,但是起码功能得差不多吧,时钟与天气都已经OK,在做日历的时候觉得比较麻烦,就去CodePen找找看,便有了如此。

源码迁移

CodePen上的原项目本身难度不高,繁琐在理清楚日历逻辑(原作者逻辑),以及将此作者项目中关于DOM的操作转换成vue的模板操作。

先看逻辑

本月1号之前有可能存在上个月的尾巴(假如我们需要将日历方格全部填满)

本月内容以及当天的样式

本月最后一天后,也有可能会有下个月的月头

分别对应了原项目中这三个函数,原作者也有注释:

lastDayOfLastMonth 上个月最后一天,这里应该是原作者命名问题,应该是lastDayOfPreviousMonth

firstDayOfMonth 本月第一天

lastDateOfMonth 本月最后一天

i 是本月第几天,走了一个do while循环

// If not Sunday but first day of the month

// it will write the last days from the previous month

if ( i == 1 ) {

html += '

';

var k = lastDayOfLastMonth - firstDayOfMonth+1;

for(var j=0; j < firstDayOfMonth; j++) {

html += '

' + k + '';

k++;

}

}

上面的意思就是第一天时候把上个月尾巴给加到表格标签里面(最后统一加)

// Write the current day in the loop

var chk = new Date();

var chkY = chk.getFullYear();

var chkM = chk.getMonth();

if (chkY == this.currYear && chkM == this.currMonth && i == this.currDay) {

html += '

' + i + '';

} else {

html += '

' + i + '';

}

上面特殊处理的今天,其他本月内容都是常规加入,可以从class上面区分看出来。

// If not Saturday, but last day of the selected month

// it will write the next few days from the next month

if ( i == lastDateOfMonth ) {

var k=1;

for(dow; dow < 6; dow++) {

html += '

' + k + '';

k++;

}

}

上面的意思就是当本月最后一天的时候,顺便把下个月的月头加进来。

漏了,每行的首尾控制

// If Sunday, start new row

if ( dow == 0 ) {

html += '

';

}

// If Saturday, closes the row

if ( dow == 6 ) {

html += '

';

}

这里说一下,因为日历是从周日到周六为一行,所以作者这里判断方案是Sunday与Saturday。

上面这些就是核心代码,当然还有下个月与上个月切换,不过就是清空当前日历再来一次,这些看源码即可,没有太多逻辑问题。

转vue

转起来难度不是很大,更多的是思维变化。

原项目是直接操作DOM,我们这里通过数据操作模板(姑且区分下),所以需要构建一个对象来承接每个”天“。

我们申明一个日历数组,由于日历是由若干个星期组成,所以我们就命名为:weeks,然后每个”天“给对象,属性如下:

{

// 哪天

label: [string],

// 是否今天

today: [boolean],

// 是否本月

current: [boolean],

}

那么我们的”天“会有这几种情况:

常规天

今天

上月或下月的天

{

// 哪天

label: [string],

// 是否本月

current: true,

}

{

// 哪天

label: [string],

// 是否今天

today: true,

// 是否本月

current: true,

}

{

// 哪天

label: [string],

}

接下来,我们把原逻辑里面对应的html,换成weeks,tr换成week(每次新建一个空数组),在周日或者第一天时候把week置空,在周六或本月最后一天把week闭合并且让weeks来push一下week,循环走完,我们一个月的关于weeks、week以及”天“的处理就完成了。

核心逻辑如下:

const y = this.year, m = this.month

let d = new Date()

// 本月第一天

, firstDayOfMonth = new Date(y, m, 1).getDay()

// 本月最后一天

, lastDateOfMonth = new Date(y, m + 1, 0).getDate()

// 上个月最后一天

, lastDayOfPreMonth = m === 0 ? new Date(y - 1, 11, 0).getDate() : new Date(y, m, 0).getDate()

let week = []

// 月第一=几天

let i = 1

do {

let dow = new Date(y, m, i).getDay()

// 周日则单独一行

if(dow === 0) {

week = []

}

// 每月第一天关于上个月尾数几天当月显示处理

else if(i === 1) {

let k = lastDayOfPreMonth - firstDayOfMonth + 1

for(let j = 0; j < firstDayOfMonth; j++) {

let obj = {

label: k,

}

week.push(obj)

k++

}

}

// 查询当天,高亮处理

let chk = new Date()

let chkY = chk.getFullYear()

let chkM = chk.getMonth()

if(chkY === this.year && chkM === this.month && i === this.day) {

week.push({

label: i,

// 本月

current: true,

today: true,

})

// 其他本月常规天

} else {

week.push({

label: i,

// 本月

current: true,

})

}

// 周六则闭合

if(dow === 6) {

this.weeks.push(week)

}

// 本月最后一天,处理下个月首几日在当月内显示

else if(i === lastDateOfMonth) {

let k = 1

for(dow; dow < 6; dow++) {

let obj = {

label: k,

}

week.push(obj)

k++

}

this.weeks.push(week)

}

i++

} while(i <= lastDateOfMonth)

注意跨年问题

最终效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值