需求:两种日历签到样式,周日历,以及月日历签到。是用框架vue-cli
- 月日历代码
export default {
data () {
return { // 所需的属性
startTime: '2019-08-15',
year: 0,
month: 0,
weekMonth: 0,
day: 0,
newDate: new Date().format('yyyy-MM-dd'),
weekList: [],
monthList: [],
monthDays: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
weekDay: 1,
lastWeekDay: 1,
preMonthSize: 0,
typeWeek: 2, // 日历类型 1:月日历; 2:周日历
preMonth: 0,
preMonthList: [],
daysList: [], // 签到日期列表
isLeak: false, // 昨天是否漏签
isSign: false // 今天是否签到
}
},
mGetDate (year, month) {
var d = new Date(year, month, 0)
return d.getDate()
},
// 根据年月日获得为星期几
getWeekDay (year, month, day) {
return new Date(`${year}/${month}/${day}`).getDay() === 0 ? 7 : new Date(`${year}/${month}/${day}`).getDay()
},
initDate () {
if ((this.year % 4 === 0 && this.year % 100 !== 0) || this.year % 400 === 0) {
this.monthDays[1] = 29
} else {
this.monthDays[1] = 28
}
// 获得指定年月的1号是星期几
const firstDay = this.getWeekDay(this.year, this.month, 1)
// 在1号前面填充多少个上个月的日期
this.weekDay = firstDay === 1 ? 0 : firstDay - 1
this.preMonthSize = this.mGetDate(this.year, this.month, 0)
this.preMonth = this.month
if (this.month === 1) {
this.preMonth = 12
} else {
this.preMonth -= 1
}
// console.log('现在的月份' + this.month)
var temTime = new Date(this.year, this.month - 1, 1)
// console.log('现在的时间' + temTime)
var arr = []
for (var i = 0; i < this.monthDays[this.month - 1]; i++) {
var ymd = temTime.format('yyyy-MM-dd')
arr.push({
'date': ymd,
'isPrize': false,
'status': 0, // 1是未签到,2是已签到,3是漏签
'showDate': temTime.getDate()
})
temTime.setDate(temTime.getDate() + 1)
}
this.monthList = arr
},
// 选择上一月,下一月
changeDate (type) {
var newTime = `${this.year}-${this.month > 9 ? this.month : '0' + this.month}`
switch (type) {
case 'preMonth':
if (newTime > this.startTime) {
if (this.month === 1) {
this.month = 12
this.year -= 1
} else {
this.month -= 1
}
this.initDate()
this.getListSignDate()
}
break
case 'nextMonth':
if (newTime < new Date(this.newDate).format('yyyy-MM')) {
if (this.month === 12) {
this.month = 1
this.year += 1
} else {
this.month += 1
}
this.initDate()
this.getListSignDate()
}
break
default:
break
}
}
}
2. 周日历代码
// 以下是周日历的方法
getMonDate (test) { // 计算周一的时间戳
if (test.getDay() === 1) {
return test
} else {
if (test.getDay() === 0) {
test.setDate(test.getDate() - 6)
} else {
test.setDate(test.getDate() - test.getDay() + 1)
}
return test
}
},
getResult (date) {
var time = new Date(date)
var timeobj = this.getMonDate(time) // timeobj是当前星期一的日期对象
// console.log(timeobj)
var temTime = new Date(timeobj.getTime()) // 当前星期一对象转换成时间戳
// console.log(temTime)
var arr = []
for (var i = 0; i < 7; i++) {
var ymd = temTime.format('yyyy-MM-dd')
var weekMonth = temTime.getMonth()+ 1
arr.push({
'date': ymd,
'isPrize': false,
'status': 0, // 1是未签到,2是已签到,3是漏签
'showDate': temTime.getDate(),
'weekMonth': weekMonth
})
temTime.setDate(temTime.getDate() + 1)
}
this.weekList = arr
},
比较函数
另外添加一个比较函数,用于当前周日历or月日历的日期与后台返回的日期数组比较,得到最终未签到,已签到,漏签数组
ergodicFun (arr1, arr2) { // status 1==未签到,2==已签到,3==漏签
// arr1(月日历数组,or周日历数组),arr2后台返回日期数组
// 后台返回数组格式 [{date: "2019-08-01", isPrize: false}, {date: "2019-08-02", isPrize: false},…]}
for (var i = 0; i < arr1.length; i++) {
var o = arr1[i]
var m = 0
var date = new Date(this.newDate).format('yyyy-MM-dd')
if (arr2 === [] || arr2 === '' || arr2 === null || arr2 === undefined || arr2.length === 0) { // 如果后台无返回数组,即无签到数据,当前日期之前的为漏签,当前日期之后的为未签到
if (o['date'] < date) {
o['status'] = 1
} else {
o['status'] = 3
}
} else { // 如果后台有返回数组,即有签到数据
for (var j = 0; j < arr2.length; j++) {
var e = arr2[j]
if (o['date'] === e['date']) {
o['status'] = 2
if (e['isPrize']) {
o['isPrize'] = true
}
} else {
m += 1
}
if (m === arr2.length) {
if (o['date'] < date) {
o['status'] = 1
} else {
o['status'] = 3
}
}
}
}
}
}
最后,template部分
<div class="signIn-content">
<span class="change-btn" v-on:click="changeTypeWeek()">{{ typeWeek === 1 ? '收起' : '展开' }} <i class="icon-arrow" :class="typeWeek === 1 ? 'top' : 'bottom'"></i></span>
<span class="sign-btn" :class="isSign === true ? 'signed-in' : ''" v-on:click="sign()">{{ isSign === true ? '已签到' : '立即签到' }}</span>
<div class="canlendarPanel">
<div class="canlendar-header" v-show="typeWeek === 1">
<p class="pre">
<span @click="changeDate('preMonth')">
<i class="icon left-small-icon" :class="{'opacity':`${this.year}-${this.month > 9 ? this.month : '0' + this.month}` <= startTime}"></i>
</span>
</p>
<p class="currenDate">{{ `${year}年${month}月` }}</p>
<p class="next">
<span @click="changeDate('nextMonth')">
<i class="icon right-small-icon" :class="{'opacity':month >= (new Date().getMonth() + 1)}"></i>
</span>
</p>
</div>
<div class="canlendar-main">
<ul class="main week" v-if="typeWeek === 2"> // 周日历部分
<li v-for="item of weekList" :key="item.date">
<span class="i-coin" v-show="item.date < newDate" :class="{'signed':item.status === 2, 'unsigned': item.status === 3 || item.status === 1 || item.status === 0, 'haveRedBag': item.isPrize === true}">
<i v-on:click="windowOpen('repairWindowFlag')"
class="repair-icon"
:class="(((item.status === 1 && (new Date(new Date(newDate).getTime() - 24 * 60 * 60 * 1000).format('yyyy-MM-dd')) === item.date)) && isLeak) && isSign? 'repair-img' : ''"></i>
</span>
<span class="i-coin" v-show="item.date >= newDate" :class="{'signed':item.status === 2, 'unsigned': item.status === 3 || item.status === 1 || item.status === 0, 'haveRedBag': showRedBag(item.date, signRuleDays, isSign)}">
<i v-on:click="windowOpen('repairWindowFlag')"
class="repair-icon"
:class="(((item.status === 1 && (new Date(new Date(newDate).getTime() - 24 * 60 * 60 * 1000).format('yyyy-MM-dd')) === item.date)) && isLeak) && isSign? 'repair-img' : ''"></i>
</span>
<span :class="{'signed-text':item.status === 2, 'missedSign-text':item.status === 1, 'unsigned-text':item.status === 3}">
{{(item.weekMonth > 9 ? item.weekMonth : '0' + item.weekMonth) + '.' + (item.showDate > 9 ? item.showDate : '0' + item.showDate)}}
</span>
</li>
</ul>
<ul class="main" v-else> // 月日历部分
<li v-for="inx in weekDay" class="disabled" :key="inx">
<span class="i-coin unsigned"></span>
<span class="unsigned-text">
{{ (preMonth> 9 ? preMonth: '0' + preMonth) + '.' + (preMonthSize - weekDay + inx) }}</span>
</li>
<li v-for="item of monthList" :key="item.date">
<span class="i-coin" v-show="item.date < newDate"
:class="{'signed':item.status === 2,
'unsigned': item.status === 3 || item.status === 1 || item.status === 0,
'haveRedBag': item.isPrize === true}"
>
<i v-on:click="windowOpen('repairWindowFlag')"
class="repair-icon"
:class="(((item.status === 1 && (new Date(new Date(newDate).getTime() - 24 * 60 * 60 * 1000).format('yyyy-MM-dd')) === item.date)) && isLeak) && isSign? 'repair-img' : ''"></i>
</span>
<span v-show="item.date >= newDate" class="i-coin"
:class="{'signed':item.status === 2, 'unsigned': item.status === 3 || item.status === 1 || item.status === 0, 'haveRedBag': showRedBag(item.date, signRuleDays, isSign)}">
<i v-on:click="windowOpen('repairWindowFlag')"
class="repair-icon"
:class="(((item.status === 1 && (new Date(new Date(newDate).getTime() - 24 * 60 * 60 * 1000).format('yyyy-MM-dd')) === item.date)) && isLeak) && isSign? 'repair-img' : ''"></i>
</span>
<span :class="{'signed-text':item.status === 2, 'missedSign-text':item.status === 1, 'unsigned-text':item.status === 3}">
{{ (month > 9 ? month : '0' + month) + '.' + (item.showDate > 9 ? item.showDate : '0' + item.showDate) }}</span
>
</li>
</ul>
</div>
</div>
</div>