可复制查看效果、该代码为完整代码,同时,里面返回的字段可根据自己的业务需求进行更改. 关键字段:
dataList是后台传过来需要显示在日历上的数据或任务,同时点击切换月份以及、对应的日期都能返回对应的月份以及当前点击的对象数据,方便进行数据请求等操作。ps:仅做记录,不喜勿喷(下次遇到同样需求,直接赋值黏贴,哈哈哈~)
一、HTML
<template>
<view class="timepicker">
<view class="current_data">直播日历:{{this.monthTitle}}</view>
<view class="timepicker-box">
<view class="box-section">
<view class="section-slider">
<view class="slider-year-month">
<image src="/static/img/index/arrow_right.png" @click="getPreMonthDayList" class="pre"></image>
<text class="year">{{this.monthTitle}}</text>
<image src="/static/img/index/arrow_right.png" @click="getNextMonthDayList" class="next">
</image>
</view>
<view class="slider-week">
<text class="week-item" :key="key" v-for="(item, key) in weekText">{{item}}</text>
</view>
<view class="slider-day">
<view :class="['day-item',item.isThisMonth?'':'not-current-month']" :key="key"
v-for="(item, key) in days" @click="changeSelItem(item,key)">
<view
:class="['day',item.isToDay?'day-item-current':'', selIndex==key?'day-item-sel':'',item.propsAttr.length?'sel':'']">
{{item.day}}
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
二、JS
<script>
import {
formatDate,
returnData,
getFirstAndLast,
isToday
} from '@/common/tools/day.js'
export default {
name: "timepicker",
data() {
return {
weekText: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],
currentDay: '', //当前几号
currentYear: '', //当前年
currentMonth: '', // 当前月
currentWeek: '', // 当前月1号是星期几? 0表示星期天
monthTitle: '',
dataList: [{
bgcolor: "#67b7f0",
id: 1180,
className: "二级建造师考试",
data: "2022-06-26"
}], //有任务的日期
thisMonthDay: [],
days: [], //所有日期
firstDay: new Date(),
weekDay: new Date().getDay(), //获取今天是周几
selIndex: -1,
};
},
props: {
//有任务的日期
//dataList: {
// require: false,
// type: Array,
// default: () => []
//}
},
computed: {},
created() {
this.firstDay.setDate(this.firstDay.getDate() - this.weekDay); //获取本周第一天的日期
this.initData()
},
methods: {
// 选中日期
changeSelItem(item, index) {
this.selIndex = index;
this.$emit('clickCurrentDay', item)
},
// 下月
getNextMonthDayList() {
this.pickNext(this.currentYear, this.currentMonth);
},
// 上月
getPreMonthDayList() {
this.pickPre(this.currentYear, this.currentMonth);
},
// 上一月 (@param year, @param month)
pickPre(year, month) {
console.log("上一月")
var d = new Date(formatDate(year, month, 1));
d.setDate(0); //设置为上个月
this.initData(formatDate(d.getFullYear(), d.getMonth() + 1, 1));
this.$emit('currentYM', {
year: this.currentYear,
month: this.currentMonth
})
},
// 下一个月 (@param year, @param month)
pickNext(year, month) {
console.log("下一个月")
var d = new Date(formatDate(year, month, 1));
d.setDate(35);
this.initData(formatDate(d.getFullYear(), d.getMonth() + 1, 1));
this.$emit('currentYM', {
year: this.currentYear,
month: this.currentMonth
})
},
// 初始化月
initData(cur) {
var date;
if (cur) {
// 切换上一月、下一月
date = new Date(cur);
} else {
var now = new Date(); // 此处取本机时间,应改为服务器时间
// console.log(now.getFullYear(), now.getMonth() + 1, 1)
var date = new Date(formatDate(now.getFullYear(), now.getMonth() + 1, 1));
}
this.currentDay = new Date().getDate(); // 今日日期 几号
this.currentYear = date.getFullYear(); // 当前年份
this.currentMonth = date.getMonth() + 1; // 当前月份
this.currentWeek = date.getDay(); // 当前月1号是星期几? 0表示星期天
// console.log(this.currentYear, this.currentMonth)
var month = this.currentMonth >= 10 ? this.currentMonth : "0" + this.currentMonth;
this.monthTitle = this.currentYear + "-" + month;
// 当前月最后一天是星期几? 0表示星期天
var nextWeek = new Date(date.getFullYear(), date.getMonth() + 1, 0).getDay();
var str = formatDate(this.currentYear, this.currentMonth, 1); // 2021/05/01
var nextStr = new Date(
date.getFullYear(),
date.getMonth() + 1,
0
).toLocaleDateString(); // 2021/05/31
var daysList = []; // 初始化日期
// 设置上一个月 需显示 的最后几天 铺满一周
for (var i = this.currentWeek; i > 0; i--) {
var d = new Date(str);
d.setDate(d.getDate() - i);
var tod = returnData(d); //获取完整日期
var dayobject = {
d: tod,
data: tod,
day: d.getDate(),
isThisMonth: d.getMonth() + 1 == this.currentMonth ? true : false,
isToDay: isToday(tod),
isSign: this.isVerDate(d),
propsAttr: this.copyAttr(d, this.dataList),
}; // 用一个对象包装Date对象 以便为以后预定功能添加属性
daysList.push(dayobject); // 将日期放入data 中的days数组 供页面渲染使用
}
// 显示当前月的天数 第二个循环为 j<= 36- currentWeek,
// 因为1号是星期六的时候当前月需显示6行,如2020年8月
var num = 0; //第几个月 每遇到1号加1
for (var j = 0; j <= 36 - this.currentWeek; j++) {
var d = new Date(str);
d.setDate(d.getDate() + j);
var tod = returnData(d); //获取完整日期
var dddd = d.getDate();
var dayobject = {
d: tod,
data: tod,
day: d.getDate(),
isThisMonth: d.getMonth() + 1 == this.currentMonth ? true : false,
isToDay: isToday(tod),
isSign: this.isVerDate(d),
propsAttr: this.copyAttr(d, this.dataList),
};
if (dddd == 1) {
num++;
}
if (num == 2) {
break;
}
daysList.push(dayobject);
}
// 设置下一个月 需显示 的最前几天铺满一周
for (var k = 1; k <= 6 - nextWeek; k++) {
var d = new Date(nextStr);
d.setDate(d.getDate() + k);
var tod = returnData(d); //获取完整日期
var dayobject = {
d: tod,
data: tod,
day: d.getDate(),
isThisMonth: d.getMonth() + 1 == this.currentMonth ? true : false,
isToDay: isToday(tod),
isSign: this.isVerDate(d),
propsAttr: this.copyAttr(d, this.dataList),
}; // 用一个对象包装Date对象 以便为以后预定功能添加属性
daysList.push(dayobject); // 将日期放入data 中的days数组 供页面渲染使用
}
// 设置本月的所有日期
this.thisMonthDay = daysList.filter((item, index) => {
if (isToday(item.d)) {
this.selIndex = index;
}
return item.isThisMonth
})
this.days = daysList;
// console.log(daysList)
},
// 判断该日期是否有任务
isVerDate(d) {
let dda = returnData(d);
this.signdays = [];
for (var i in this.sign_Month) {
this.signdays.push(this.sign_Month[i].data);
}
return this.signdays.includes(dda);
},
// 复制元素的所有属性
copyAttr(d, List, type) {
// 日期 原数组
var dd = null;
if (type) {
dd = d;
} else {
dd = returnData(d);
}
var ArrayList = [];
if (List.length > 0) {
List.forEach(item => {
if (item.data == dd) {
// item.tt = getHourAndMin(item.start) + '-' + getHourAndMin(item.end)
ArrayList.push(item)
}
})
return ArrayList
} else {
return []
}
},
}
};
</script>
day.js
// 返回 类似 2020/01/01 格式的字符串 ok
const formatDate = function(year, month, day) {
month < 10 && (month = "0" + month);
day < 10 && (day = "0" + day);
return year + "-" + month + "-" + day;
};
//获取完整日期
const returnData = function(d) {
var year = d.getFullYear();
var month = d.getMonth() + 1;
var day = d.getDate();
var m = month >= 10 ? month : "0" + month;
var daa = day >= 10 ? day : "0" + day;
return year + "-" + m + "-" + daa;
};
// 获取本月第一天和最后一天
const getFirstAndLast = function(d, type = null) {
var obj = {},
arr = [],
now,
nowMonth,
nowYear;
if (d) {
now = new Date(d); //当前日期
nowMonth = now.getMonth(); //当前月
nowYear = now.getFullYear(); //当前年
} else {
now = new Date(); //当前日期
nowMonth = now.getMonth(); //当前月
nowYear = now.getFullYear(); //当前年
}
//本月的开始时间
var monthStartDate = new Date(nowYear, nowMonth, 1);
var startY = monthStartDate.getFullYear();
var startM = monthStartDate.getMonth() + 1;
var startD = monthStartDate.getDate();
var SAllTime = startY + "-" + startM + "-" + startD + " 00:00:00";
if (type) {
var firstTime = startY + "-" + startM + "-" + startD;
}
//本月的结束时间
var monthEndDate = new Date(nowYear, nowMonth + 1, 0);
var endY = monthEndDate.getFullYear();
var endM = monthEndDate.getMonth() + 1;
var endD = monthEndDate.getDate();
var EAllTime = endY + "-" + endM + "-" + endD + " 23:59:59";
if (type) {
var EndTime = endY + "-" + endM + "-" + endD;
}
var dStart = new Date(SAllTime);
var dEnd = new Date(EAllTime);
// console.log(monthStartDate,monthEndDate)
if (type) {
arr = [{
data: firstTime
},
{
data: EndTime
}
];
} else {
obj = {
start: dStart,
end: dEnd
};
}
var data1 = new Date(obj.start);
var data2 = new Date(obj.end);
if (type) {
return arr;
} else {
return {
startTime: data1.getTime() / 1000,
endTime: data2.getTime() / 1000
};
}
};
// 判断是否为今天
const isToday = function(str) {
var d = new Date();
var y = d.getFullYear(); // 年
var m = d.getMonth() + 1; // 月份从0开始的
var d = d.getDate(); //日
let ma = m >= 10 ? m : "0" + m;
let da = d >= 10 ? d : "0" + d;
return str == y + "-" + ma + "-" + da;
};
export {
formatDate,
returnData,
getFirstAndLast,
isToday
}
三、CSS
<style lang="scss" scoped>
.timepicker {
width: 100%;
padding: 30rpx;
box-sizing: border-box;
.timepicker-box {
display: flex;
flex-direction: column;
width: 100%;
height: auto;
background: #fff;
.box-section {
position: relative;
flex: 1;
.section-slider {
display: flex;
flex-direction: column;
.slider-year-month {
padding: 12rpx 10%;
display: flex;
align-items: center;
justify-content: space-between;
.pre {
width: 40rpx;
height: 40rpx;
transform: rotate(180deg);
}
.next {
width: 40rpx;
height: 40rpx;
}
}
.slider-week {
display: flex;
font-weight: bold;
align-items: center;
color: #333;
.week-item {
flex: 1;
font-size: 32rpx;
padding: 15rpx 0 20rpx;
border-bottom: 1px solid #eee;
text-align: center;
}
}
.slider-day {
padding: 10rpx 0;
display: flex;
flex-wrap: wrap;
.day-item {
display: flex;
align-items: center;
justify-content: center;
color: #333;
width: 14.28%;
height: 80rpx;
text-align: center;
font-size: 28rpx;
.day {
width: 70rpx;
line-height: 70rpx;
height: 70rpx;
border-radius: 50%;
position: relative;
}
.sel:after {
position: absolute;
display: block;
content: "";
width: 6rpx;
height: 6rpx;
margin: auto;
border-radius: 50%;
background: #677FD2;
left: 0;
right: 0;
bottom: 0;
}
}
.day-item-current {
color: red;
background: #EAEAEA;
}
.day-item-sel {
background: #677FD2;
color: #fff;
}
.not-current-month {
.day {
color: #c9c6c6;
}
}
}
}
}
.box-footer {
flex-basis: 10%;
display: flex;
box-shadow: 0px -1px 0px #eee;
.footer-btn {
flex: 1;
text-align: center;
span {
font-size: 16px;
}
&:not(:last-child) {
box-shadow: 1px 0px 0px #eee;
}
}
}
}
}
</style>