展开时效果:

收起时效果:

主要功能
1、切换左右箭头切换月份
2、点击今天按钮:回到今天日期并选中查询接口
3、黄点代表有日程,点击选中,并且查询,下方对应展示日程内容,有数据则显示,无数据则显示暂无数据
4、点击某一日期,蓝色选中效果,并查询当前日期的数据 5、点击下拉箭头,展开或收起日程
具体代码实现:
bash
<template>
<div :class="[showAll == true ? 'active' : '','schedule-calendar']">
<div class="calendar-box">
<!-- 年月 -->
<div class="calendar-top">
<div class="yearMonth">
{{ currentYear }}年{{ currentMonth }}月
</div>
<div class="today-btn" @click="toToday()">今天</div>
<div class="operate-arrow">
<i class="el-icon-arrow-left ope-left" @click="pickPre(currentYear,currentMonth)"></i>
<i class="el-icon-arrow-right ope-right" @click="pickNext(currentYear,currentMonth)"></i>
</div>
</div>
<!-- 星期 -->
<div class="weekdays">
<div>一</div>
<div>二</div>
<div>三</div>
<div>四</div>
<div>五</div>
<div>六</div>
<div>日</div>
</div>
<!-- 日期 -->
<div class="days-item">
<div @click="pick(day,index)" v-for="(day, index) in days" :key="index" class="time-normal">
<!--今天-->
<span v-if="day.getFullYear() == new Date().getFullYear() && day.getMonth() == new Date().getMonth() && day.getDate() == new Date().getDate()" :class="[curShow == true ? 'time-active' : '']">{{ day.getDate() }}</span>
<span v-else :class="[selectedCur == index ? 'time-active' : '']">{{ day.getDate() }}</span>
<div v-for="(item, index) in timeData" :key="index">
<i class="dots" v-if="item.scheduleAvailable == 1 && item.weeklyDate == formatDate(day.getFullYear(),day.getMonth()+1,day.getDate())"></i>
</div>
</div>
</div>
</div>
<div :class="[arrowBottom == true ? 'active' : '','arrow-btn']" @click="btnClick">》</div>
<!-- 日程数据列表 -->
<div class="schedule-list" v-if="timeData.length" :style="calcScheduleHeght()"></div>
</div>
</template>
bash
<script>
export default {
data() {
return {
timeData:[],//存放日程数据
currentYear: "", // 年份
currentMonth: "", // 月份
currentDay: "", // 日期
currentWeek: "", // 星期
days: [],
selectedCur:null,//选中的当前日期index
timeNow:"",//今日
curShow:true,//今日默认选中效果
dateCur:null,//选中的当前日期
showAll:false,//默认折叠
arrowBottom:false,//折叠按钮默认折叠状态
defaultTimes:""//今日(年+月+01)
}
},
mounted() {
this.getCurrentDate() // 获取当前时间
this.initData(this.defaultTimes)//初始化days列表数据
this.dateCur = this.timeNow
this.getScheduleData(this.defaultTimes)//选中的日期(年+月+01)去查询日程接口
},
methods: {
//我的日程数据
getScheduleData(time) {
this.$http({
url: this.$http.adornUrl('******/mySchedule'),
method: "get",
params: {
switchDate: time,
}
}).then(res => {
console.log("日程:",res)
if(res.data && res.data.length){
this.timeData = res.data
}
}).catch(err => {
console.log(err)
});
},
//回到今日
toToday(){
this.selectedCur = null
this.curShow = true
this.getCurrentDate() // 获取当前时间
this.initData(this.defaultTimes)
this.dateCur = this.timeNow
this.getScheduleData(this.dateCur)
this.showAll = true
this.arrowBottom = true
},
// 日期相关
getDate() {
const date = new Date();
let year = date.getFullYear();
let month = date.getMonth() + 1;
let day = date.getDate();
month = month > 9 ? month : '0' + month;
day = day > 9 ? day : '0' + day;
return `${year}-${month}-${day}`;
},
//年+月+01
defaultTime(){
const date = new Date();
let year = date.getFullYear();
let month = date.getMonth() + 1;
month = month > 9 ? month : '0' + month;
return `${year}-${month}-01`;
},
getCurrentDate() {
this.timeNow = this.getDate({
format: true
})
console.log("今日:",this.timeNow)
this.defaultTimes = this.defaultTime({
format: true
})
console.log("今日(年+月+01):",this.defaultTimes)
},
formatDate (year, month, day) {
const y = year
let m = month
if (m < 10) m = `0${m}`
let d = day
if (d < 10) d = `0${d}`
return `${y}-${m}-${d}`
},
initData (cur) {
let date = ''
if (cur) {
date = new Date(cur)
} else {
date = new Date()
}
this.currentDay = date.getDate() // 今日日期 几号
this.currentYear = date.getFullYear() // 当前年份
this.currentMonth = date.getMonth() + 1 // 当前月份
this.currentWeek = date.getDay() // 1...6,0 // 星期几
if (this.currentWeek === 0) {
this.currentWeek = 7
}
const str = this.formatDate(this.currentYear, this.currentMonth, this.currentDay) // 今日日期 年-月-日
this.days.length = 0
// 今天是周日,放在第一行第7个位置,前面6个 这里默认显示一周,如果需要显示一个月,则第二个循环为 i<= 35- this.currentWeek
/* eslint-disabled */
for (let i = this.currentWeek - 1; i >= 0; i -= 1) {
const d = new Date(str)
d.setDate(d.getDate() - i)
this.days.push(d)
}
for (let i = 1; i<= 35- this.currentWeek; i += 1) {
const d = new Date(str)
d.setDate(d.getDate() + i)
this.days.push(d)
}
},
// 上一個月 传入当前年份和月份
pickPre (year, month) {
const d = new Date(this.formatDate(year, month, 1))
d.setDate(0)
this.dateCur = this.formatDate(d.getFullYear(), d.getMonth() + 1, 1)
this.initData(this.dateCur)
this.getScheduleData(this.dateCur)
// 点击上月时把点击选中清空
this.selectedCur = null
},
// 下一個月 传入当前年份和月份
pickNext (year, month) {
const d = new Date(this.formatDate(year, month, 1))
d.setDate(35)
this.dateCur = this.formatDate(d.getFullYear(), d.getMonth() + 1, 1)
this.initData(this.dateCur)
this.getScheduleData(this.dateCur)
// 点击下月时把点击选中清空
this.selectedCur = null
},
// 当前选择日期
pick (date,index) {
console.log(index)
this.selectedCur = index
this.dateCur = this.formatDate(date.getFullYear(), date.getMonth() + 1, date.getDate())
if(this.timeNow == this.dateCur){
this.curShow = true
}else{
this.curShow = false
}
this.getScheduleData(this.dateCur)
},
//折叠按钮点击
btnClick(){
if(this.showAll == false){
this.showAll = true
this.arrowBottom = true
}else{
this.showAll = false
this.arrowBottom = false
}
},
//动态计算盒子高度
calcScheduleHeght(){
if(window.innerHeight < 832){
return { height: '200px' };
}else{
if(this.showAll == false){
return { height: `calc( 100% - 170px)`};
}else{
return { height: `calc( 100% - 355px)`};
}
}
}
}
}
</script>
样式
bash
/* 日程 */
.schedule-calendar{
background: #ECF6FF;
border-radius: 8px;
height: 123px;
margin-bottom:10px;
overflow:hidden;
position: relative;
}
.schedule-calendar.active{
height: 305px;
}
.calendar-box{
position: relative;
}
.schedule-list{
/* height: calc(100% - 170px); */
overflow: hidden;
overflow-y: auto;
}
.schedule-list::-webkit-scrollbar {
width: 5px;
}
.schedule-list::-webkit-scrollbar-thumb {
border-radius: 8px;
background-color: #ccc;
}
.schedule-list::-webkit-scrollbar-track {
border-radius: 8px;
background-color: #e7e7e7;
border: 1px solid #cacaca;
}
.yearMonth{
font-size: 12px;
color: #666666;
text-align: left;
padding-top: 8px;
padding-left: 15px;
margin-bottom:10px;
text-align: center;
}
.today-btn{
width: 39px;
height: 20px;
line-height: 20px;
border-radius: 60px;
background: #FFFFFF;
box-sizing: border-box;
border: 1px solid #EEEEEE;
font-size: 10px;
color: #666666;
cursor: pointer;
position:absolute;
top:7px;
right:7px;
}
.weekdays{
display: flex;
align-items: center;
justify-content: space-around;
margin-bottom:10px;
font-size: 14px;
color: #666666;
}
.days-item{
height:46px;
line-height:46px;
text-align: center;
display: flex;
align-items: center;
justify-content: space-around;
font-size: 14px;
font-weight: bold;
color: #3D3D3D;
flex-wrap: wrap;
}
.time-normal{
cursor: pointer;
width: 14%;
height: 46px;
padding: 0 14px 0 14px;
box-sizing: border-box;
}
.time-active{
width: 37px;
height: 46px;
border-radius: 4px;
background: linear-gradient(332deg, #2CA7FF -8%, #69BBFF 58%, #90D5FF 112%);
cursor: pointer;
display: block;
margin: 0 auto;
}
.arrow-btn{
position: absolute;
bottom: 0;
left: 50%;
margin: 0 auto;
margin-left:-2%;
cursor: pointer;
width: 25px;
height: 25px;
text-align:center;
transform: rotate(90deg);
transition:all 0.4s ease 0s;
}
.arrow-btn.active{
transform: rotate(-90deg);
}
i.dots{
width: 6px;
height: 6px;
border-radius: 6px;
background: linear-gradient(180deg, #FFB00E 0%, #FF683F 100%);
display: block;
margin: 0 auto;
margin-top: -13px;
}
.operate-arrow i {
color: #90A7FF;
font-weight: bold;
cursor: pointer;
position: absolute;
top:9px;
}
i.ope-left{
left:180px;
}
i.ope-right{
right:166px;
}