Vue日历日程组件
原文链接 https://www.jb51.net/article/212767.htm
与原文对比修改了太多,不作详细描述
效果预览
vue组件代码
<template>
<div class="wh-container">
<div class="wh-content-all">
<div class="wh-top-change">
<span class="wh-arrow-left">
<i @click="PreYear" class="el-icon-d-arrow-left"></i>
<i @click="PreMonth" class="el-icon-arrow-left"></i>
</span>
<span class="wh-content-li">{{ dateTop }}</span>
<span class="wh-arrow-right">
<i @click="NextMonth" class="el-icon-arrow-right"></i>
<i @click="NextYear" class="el-icon-d-arrow-right"></i>
</span>
</div>
<div class="wh-content">
<div class="wh-content-item" v-for="(tag,index) in textTop" :key="index">
<div class="wh-top-tag">{{ tag }}</div>
</div>
<div
class="wh-content-item"
v-for="(item,index) in dayList" :key="index"
@click="clickDay(item,index)">
<div
class="date-box"
:class="{'wh-isToday':item.isToday,'wh-choose-day':item.chooseDay,'holiday':item.holiday}">
<div
class="wh-item-date"
:class="{'wh-other-dayHide':item.otherMonth!=='nowMonth','wh-want-dayHide':item.dayHide}">
{{ item.id }}
</div>
<div class="date-sign">
<i v-if="item.leave"
:style="[{background:(item.leave)?'red':''}]"
class="sign"></i>
<i v-if="item.meeting"
:style="[{background:(item.meeting)?'rgb(244 184 73)':''}]" class="sign"></i>
<i v-if="item.business"
:style="[{background:(item.business)?'#639af1':''}]"
class="sign"></i>
<i v-if="item.egress"
:style="[{background:(item.egress)?'rgb(145,204,117)':''}]"
class="sign"></i>
</div>
</div>
</div>
</div>
<div class="tags">
<span><i style="background-color:red;"></i>请假</span>
<span><i style="background-color:rgb(244,184,73);"></i>会议</span>
<span><i style="background-color:#639af1;"></i>出差</span>
<span><i style="background-color:rgb(145,204,117);"></i>外出</span>
</div>
</div>
</div>
</template>
<script>
import timeUtil from "./calendar.js";
import {dateFormat} from "@/util/date";
export default {
name: "Calendar",
components: {},
data() {
return {
textTop: ["日", "一", "二", "三", "四", "五", "六"],
scheduleDialogVisible: false, // 新建日程弹窗
dayList: [],
historyChose: [],
dateTop: "",
currentDate: new Date(),//当前日期
leave: [], // 当前月份 请假 日期列表
meeting: [], // 当前月份 会议 日期列表
business: [], // 当前月份 出差 日期列表
egress: [], // 当前月份 外出 日期列表
attendance: [], // 当前月份 日程列表
holiday: [], // 节假日
scheduleEditDialogVisible: false, // 修改日程弹窗
scheduleData: [] // 修改日程数据
};
},
computed: {},
mounted() {
this.getList();
},
methods: {
// 查询日程
getUserAttendance() {
this.leave = [
"2023-09-07",
"2023-09-08",
"2023-09-09"
]
this.meeting = [
"2023-09-08",
"2023-09-09"
]
this.business = [
"2023-09-08"
]
this.egress = [
"2023-09-08",
"2023-09-07"
]
this.holiday = [
"2023-09-30",
"2023-09-29",
"2023-09-24",
"2023-09-23",
"2023-09-17",
"2023-09-16",
"2023-09-10",
"2023-09-09",
"2023-09-03",
"2023-09-02"
] // 节假日
this.setDaySign()
},
// 点击日期
clickDay(item) {
if (item.otherMonth == "preMonth") {
// 切换至上个月
this.PreMonth(item.date)
} else if (item.otherMonth == "nextMonth") {
// 切换至下个月
this.NextMonth(item.date)
} else if (item.otherMonth == "nowMonth") {
// 如果有日程,则查询
if (item.leave || item.meeting || item.business || item.egress) {
// this.searchUserAttendanceList(item)
}
}
},
PreMonth() {
this.currentDate = timeUtil.getOtherMonth(this.currentDate, "preMonth");
this.getList();
},
NextMonth() {
this.currentDate = timeUtil.getOtherMonth(this.currentDate, "nextMonth");
this.getList();
},
PreYear() {
this.currentDate = timeUtil.getOtherYear(this.currentDate, "preYear");
this.getList();
},
NextYear() {
this.currentDate = timeUtil.getOtherYear(this.currentDate, "nextYear");
this.getList();
},
async getList() {
this.dateTop = dateFormat(this.currentDate, "yyyy年MM月");
this.dayList = timeUtil.getMonthList(this.currentDate);
// 获取日期后,查询日程
this.getUserAttendance()
},
// 设置日程标记
setDaySign() {
for (let index in this.dayList) {
let item = this.dayList[index]
item.leave = this.leave.indexOf(item.date) > -1; // 请假
item.meeting = this.meeting.indexOf(item.date) > -1; // 会议
item.business = this.business.indexOf(item.date) > -1; // 出差
item.egress = this.egress.indexOf(item.date) > -1; // 外出
item.holiday = this.holiday.indexOf(item.date) > -1; // 节假日
}
this.dayList.splice(0, 0)
}
},
};
</script>
<style scoped lang="scss">
.wh-container {
padding: 10px;
height: calc(100% - 20px);
.wh-content-all {
background-color: #fff;
width: 100%;
overflow: hidden;
height: calc(100% - 42px);
.wh-top-change {
display: flex;
justify-content: space-around;
align-items: center;
span {
cursor: pointer;
display: flex;
color: $main-color-blue;
font-weight: 700;
font-size: 16px;
justify-content: center;
align-items: center;
height: 48px;
}
.wh-content-li {
cursor: auto;
width: 140px;
}
.wh-arrow-left, .wh-arrow-right {
color: #999;
flex: 1;
&:active {
color: $main-color-blue;
}
i {
margin: 0 5px;
}
}
}
.wh-content {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
height: calc(100% - 48px - 20px);
.wh-content-item {
width: 14%;
font-size: 16px;
color: #333;
//height: 16%;
display: flex;
align-items: center;
.date-box {
height: 30px;
width: 30px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
cursor: pointer;
border-radius: 4px;
&.holiday {
background: rgba(254, 245, 245, 1);
color: rgb(235, 51, 51);
}
&:hover {
background: rgba(29, 128, 254, 0.1);
}
&.wh-isToday {
background: rgba(29, 128, 254, 0.1);
//background: $main-color-blue;
//border-radius: 4px;
//color: black;
}
.wh-item-date {
width: 30px;
//height: 30px;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
}
.date-sign {
//width: 10px;
height: 6px;
display: flex;
//flex-direction: column;
justify-content: center;
align-items: center;
.sign {
display: inline-block;
width: 4px;
height: 4px;
margin: 1px;
border-radius: 2px;
}
}
}
}
}
.tags {
font-size: 12px;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
span {
padding: 0 6px;
display: flex;
align-items: center;
justify-content: center;
i {
display: inline-block;
width: 4px;
height: 4px;
border-radius: 2px;
margin-right: 5px;
}
}
}
}
}
.calendar-btm {
cursor: pointer;
height: 45px;
color: $main-color-blue;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid $main-color-blue;
border-radius: 7px;
i {
margin-right: 10px;
}
}
.wh-content:first-child .wh-content-item-tag,
.wh-content:first-child .wh-content-item {
color: #ddd;
font-size: 16px;
}
.wh-top-tag {
width: 30px;
display: flex;
justify-content: center;
align-items: center;
}
.wh-content-item .wh-other-dayHide {
color: #bfbfbf;
}
.wh-content-item .wh-want-dayHide {
color: #bfbfbf;
}
.wh-content-item .wh-choose-day {
background: #fff;
color: black;
//border-radius: 100px;
}
</style>
js代码 calendar.js
import {dateFormat} from "@/util/date";
export default {
// 当某月的天数
getDaysInOneMonth(date) {
const year = date.getFullYear();
const month = date.getMonth() + 1;
const d = new Date(year, month, 0);
return d.getDate();
},
// 向前空几个
getMonthweek(date) {
const year = date.getFullYear();
const month = date.getMonth() + 1;
const dateFirstOne = new Date(year + '-' + month + '-1');
return this.sundayStart ?
dateFirstOne.getDay() == 0 ? 7 : dateFirstOne.getDay() :
dateFirstOne.getDay() == 0 ? 6 : dateFirstOne.getDay() - 1;
},
/**
* 获取当前日期上个月或者下个月
*/
getOtherMonth(date, str = 'nextMonth') {
const timeArray = this.dateFormat(date).split('-');
const year = timeArray[0];
const month = timeArray[1];
const day = timeArray[2];
let year2 = year;
let month2;
if (str === 'nextMonth') {
month2 = parseInt(month) + 1;
if (month2 == 13) {
year2 = parseInt(year2) + 1;
month2 = 1;
}
} else {
month2 = parseInt(month) - 1;
if (month2 == 0) {
year2 = parseInt(year2) - 1;
month2 = 12;
}
}
let day2 = day;
const days2 = new Date(year2, month2, 0).getDate();
if (day2 > days2) {
day2 = days2;
}
if (month2 < 10) {
month2 = '0' + month2;
}
if (day2 < 10) {
day2 = '0' + day2;
}
const t2 = year2 + '-' + month2 + '-' + day2;
return new Date(t2);
},
/**
* 获取当前日期上一年或者下一年
*/
getOtherYear(date, str = 'nextYear') {
let year = new Date(date).getFullYear();
let month = new Date(date).getMonth() + 1;
let day = new Date(date).getDate();
let month2;
if (str === 'nextYear') {
year = parseInt(year) + 1;
} else {
year = parseInt(year) - 1;
}
let days2 = new Date(year, month, 0).getDate();
if (day > days2) {
day = days2;
}
if (month < 10) {
month2 = '0' + month;
}
if (day < 10) {
day = '0' + day;
}
const t2 = year + '-' + month2 + '-' + day;
return new Date(t2);
},
// 上个月末尾的一些日期
getLeftArr(date) {
const arr = [];
const leftNum = this.getMonthweek(date);
const num = this.getDaysInOneMonth(this.getOtherMonth(date, 'preMonth')) - leftNum + 1;
const preDate = this.getOtherMonth(date, 'preMonth');
// 上个月多少开始
for (let i = 0; i < leftNum; i++) {
const nowTime = this.dateFormat(new Date(preDate.setDate(num + i)));
arr.push({
id: num + i,
date: nowTime,
isToday: false,
otherMonth: 'preMonth',
});
}
return arr;
},
// 下个月末尾的一些日期
getRightArr(date) {
const arr = [];
const nextDate = this.getOtherMonth(date, 'nextMonth');
const leftLength = this.getDaysInOneMonth(date) + this.getMonthweek(date);
const _length = 7 - leftLength % 7;
for (let i = 0; i < _length; i++) {
const nowTime = this.dateFormat(new Date(nextDate.setDate(i + 1)));
arr.push({
id: i + 1,
date: nowTime,
isToday: false,
otherMonth: 'nextMonth',
});
}
return arr;
},
// format日期
dateFormat(date) {
return dateFormat(date, "yyyy-MM-dd")
},
// 获取某月的列表不包括上月和下月
getMonthListNoOther(date) {
const arr = [];
const num = this.getDaysInOneMonth(date);
const toDay = this.dateFormat(new Date());
for (let i = 0; i < num; i++) {
const nowTime = this.dateFormat(new Date(date.setDate(i + 1)));
arr.push({
id: i + 1,
date: nowTime,
isToday: toDay == nowTime,
otherMonth: 'nowMonth',
});
}
return arr;
},
// 获取某月的列表 用于渲染
getMonthList(date) {
return [...this.getLeftArr(date), ...this.getMonthListNoOther(date), ...this.getRightArr(date)];
},
// 默认是周一开始
sundayStart: true, // 从周日开始
};
时间格式化函数 dateFormat
/**
* 日期格式化
*/
export function dateFormat(date, format) {
format = format || 'yyyy-MM-dd hh:mm:ss';
if (date !== 'Invalid Date') {
let o = {
"M+": date.getMonth() + 1, //month
"d+": date.getDate(), //day
"h+": date.getHours(), //hour
"m+": date.getMinutes(), //minute
"s+": date.getSeconds(), //second
"q+": Math.floor((date.getMonth() + 3) / 3), //quarter
"S": date.getMilliseconds() //millisecond
}
if (/(y+)/.test(format)) format = format.replace(RegExp.$1,
(date.getFullYear() + "").substr(4 - RegExp.$1.length));
for (let k in o)
if (new RegExp("(" + k + ")").test(format))
format = format.replace(RegExp.$1,
RegExp.$1.length === 1 ? o[k] :
("00" + o[k]).substr(("" + o[k]).length));
return format;
}
return '';
}