效果图
引用
<calendar @click-event="getDate" :startDate="new Date()"></calendar>
组件代码
<template>
<div class="calendar-container">
<div class="year">
<div>
<span class="fl" @click="lastYear">«</span>
<span class="fl" @click="lastMonth">‹</span>
<p>{{nowDate.year}}年{{nowDate.month+1}}月</p>
<span class="fr" @click="nextYear">»</span>
<span class="fr" @click="nextMonth">›</span>
</div>
</div>
<ul class="week">
<li v-for="(o,index) in 7" :key="o">{{formatWeek(index)}}</li>
</ul>
<ul class="date">
<li @click="clickProv" class="none-week" v-for="o in lastMonthDays" :key="o+50" >{{lastMonthStartDay+o-1}}</li>
<li @click="clickEvent" v-for="day in nowMonthDays" :key="day"><span :class="`${nowDate.year==onDate.year&&nowDate.month==onDate.month&&day==onDate.day?'onDate':''} ${nowDate.year==onClick.year&&nowDate.month==(onClick.month-1)&&day==onClick.day?'onClick':''}`">{{day}}</span></li>
<li @click="clickNext" class="none-week" v-for="day in (42-lastMonthDays-nowMonthDays)" :key="day+100">{{day}}</li>
</ul>
</div>
</template>
<script>
export default {
props: {
startDate:{
type:Date
}
},
data () {
return {
selectDate: [],//选择日期列表
nowDate: this.getDate(new Date()), //当前设置时间 默认为当前系统时间
onDate:{year:this.getDate(new Date()).year,month:this.getDate(new Date()).month,day:this.getDate(new Date()).date},
onClick:{year:this.getDate(new Date()).year,month:this.getDate(new Date()).month+1,day:this.getDate(new Date()).date}
}
},
computed: {
lastMonthDays () {
return this.startWeek()
},
lastMonthStartDay () {
return this.calcLastMonthDays(this.nowDate.year,this.nowDate.month)-(this.startWeek()-1)
},
nowMonthDays () {
return this.calcDays(this.nowDate.year,this.nowDate.month)
}
},
created () {
if(this.startDate) {
this.nowDate = this.getDate(this.startDate)
}
},
methods: {
getDate (date) {
return {
year: date.getFullYear(),
month: date.getMonth(),
day: date.getDay(),
date: date.getDate()
}
},
formatWeek (day) {
switch (day) {
case 0:
return '日';
case 1:
return '一'
case 2:
return '二';
case 3:
return '三'
case 4:
return '四'
case 5:
return '五'
case 6:
return '六'
}
},
//判断闰年
isLeapYear (year) {
return (year % 4 == 0) && (year % 100 != 0 || year % 400 == 0);
},
//根据日子计算星期
calcWeekend (year,month,day) {
return new Date(year,month,day).getDay();
},
//计算某年某月的天数
calcDays (year,month) {
const monthDay = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
if(this.isLeapYear(year)&&month===1)
return 29
else
return monthDay[month]
},
//计算上个月天数
calcLastMonthDays (year,month) {
if(month===0) {
return this.calcDays(year-1,11)
}else {
return this.calcDays(year,month-1)
}
},
//上月
lastMonth () {
if(this.nowDate.month===0) {
this.nowDate.month = 11
this.nowDate.year --
}else {
this.nowDate.month --
}
},
//下月
nextMonth () {
if(this.nowDate.month===11) {
this.nowDate.month = 0
this.nowDate.year ++
}else {
this.nowDate.month ++
}
},
//去年
lastYear () {
this.nowDate.year --
},
//下一年
nextYear () {
this.nowDate.year ++
},
//计算当月开始星期
startWeek () {
return this.calcWeekend(this.nowDate.year,this.nowDate.month,1)
},
clickEvent (e) {
let monthNo = this.nowDate.month;
let month = monthNo<=11?(monthNo+1):0
let date = {
year:this.nowDate.year,
month:month,
week: new Date(this.nowDate.year,this.nowDate.month,e.target.innerText).getDay(),
day:Number(e.target.innerText)
}
this.onClick = date
this.$emit('click-event',date);
},
clickProv(e){
this.lastMonth()
this.clickEvent(e)
},
clickNext(e){
this.nextMonth()
this.clickEvent(e)
}
}
}
</script>
<style scoped>
.year {
text-align: center;
height: 30px;
line-height: 30px;
background: #E0ECFF;
font-size: 12px;
}
.week,.date{
box-sizing: border-box;
display: flex;
flex-wrap: wrap;
list-style: none;
}
.week {
background: #F4F4F4;
}
.week li{
height: 20px;
line-height: 20px;
}
.date li{
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
line-height: 25px;
}
.date li span{
display: block;
width: 25px;
height: 25px;
}
.date li .onDate{
color: #0000ff;
}
.date li .onClick{
background: #0080cb;
border-radius:50%;
color: #fff;
}
ul>li {
font-size: 12px;
width: calc(100%/7);
height: 30px;
text-align: center;
line-height: 30px;
color: #333;
}
.none-week {
color: #aaa;
}
.year>div {
height: 30px;
overflow: hidden;
}
.year span {
line-height: 27px;
font-size: 20px;
display: inline-block;
width: 10%;
cursor: pointer;
}
.year p {
width: 50%;
display: inline-block;
}
.fl {
float: left;
}
.fr {
float: right;
}
</style>