VUE篇之日历组件
1.简单日历组件展示
思路:根据当前月的第一天是星期几,来显示日期
<template>
<div class="wrap">
<el-button @click="preMonth">上个月</el-button>
<el-tag>当前年份{{ curYear }}</el-tag>
<el-tag>当前月份{{ curMonth }}</el-tag>
<el-button @click="nextMonth">下个月</el-button>
<div class="weeks">
<div v-for="item in week" :key="item" class="week">{{ item }}</div>
</div>
<div class="days">
<!-- 当月 -->
<div v-for="item in curDays" :key="item + 'cur'" class="curday">{{ item }}</div>
</div>
</div>
</template>
<script>
import moment from 'moment';
moment.suppressDeprecationWarnings = true;
export default {
data() {
return {
curYear: moment().year(), //当前年
curMonth: moment().month() + 1, //当前月
week: ['一', '二', '三', '四', '五', '六', '七'],
firstDay: moment(`${moment().year()}-${moment().month() + 1}`)
.startOf('month')
.day(), //获取当月第一天是星期几;星期日为 0,星期六为 6
curDays: moment().daysInMonth() //获取当月一共有多少天
};
},
methods: {
preMonth() {
this.curMonth--;
// 如果小于1表示上一年;重置日期
if (this.curMonth < 1) {
this.curYear--;
this.curMonth = 12;
}
this.curDays = moment(`${this.curYear}-${this.curMonth}`).daysInMonth();
this.firstDay = moment(`${this.curYear}-${this.curMonth}`).startOf('month').day();
if (this.firstDay == 0) {
this.firstDay = 7;
}
},
nextMonth() {
this.curMonth++;
// 如果超过12表示下一年;重置日期
if (this.curMonth > 12) {
this.curYear++;
this.curMonth = 1;
}
this.curDays = moment(`${this.curYear}-${this.curMonth}`).daysInMonth();
this.firstDay = moment(`${this.curYear}-${this.curMonth}`).startOf('month').day();
if (this.firstDay == 0) {
this.firstDay = 7;
}
}
}
};
</script>
<style lang="scss">
.wrap {
width: 700px;
height: 100%;
.weeks {
width: 100%;
height: 50px;
display: flex;
.week {
width: 100px;
line-height: 50px;
text-align: center;
background: gainsboro;
}
}
.days {
display: flex;
flex-wrap: wrap;
.lastday,
.curday {
width: 100px;
line-height: 50px;
text-align: center;
}
.lastday {
color: gold;
}
}
}
</style>
2.日历组件增强版------带有上个月或者下个月日期
较比上一版本,这个版本多了2个方法,主要用于更新上个月剩余日期,以及下个月最新日期
上个月日期:
// 获取上个月剩余天数
getPreMonthDays() {
if (this.firstDay == 1) return; //表示上个月无剩余天数
let month = this.curMonth;
let year = this.curYear;
month--;
if (month == 0) {
year--;
month = 12;
}
// 获取上个月的天数
const days = moment(`${year}-${month}`).daysInMonth();
this.preDays = days;
},
下个月日期:
// 获取下个月要显示的天数
getNextMonthDays() {
let month = this.curMonth;
let year = this.curYear;
// 获取当月最后一天是星期几
const lastDay = moment(`${year}-${month}`).endOf('month').day();
this.nextDays = lastDay == 0 ? 7 : lastDay;
}
整体代码:
<template>
<div class="wrap">
<el-button @click="preMonth">上个月</el-button>
<el-tag>当前年份{{ curYear }}</el-tag>
<el-tag>当前月份{{ curMonth }}</el-tag>
<el-button @click="nextMonth">下个月</el-button>
<div class="weeks">
<div v-for="item in week" :key="item" class="week">{{ item }}</div>
</div>
<div class="days">
<!-- 上个月 -->
<div v-for="item in firstDay - 1" :key="item + 'pre'" class="lastday">
{{ preDays - (firstDay - 1 - item) }}
</div>
<!-- 当月 -->
<div v-for="item in curDays" :key="item + 'cur'" class="curday">{{ item }}</div>
<!-- 下个月 -->
<div v-for="item in 7 - nextDays" :key="item + 'next'" class="lastday">
{{ item }}
</div>
</div>
</div>
</template>
<script>
import moment from 'moment';
moment.suppressDeprecationWarnings = true;
export default {
data() {
return {
preDays: 30,
nextDays: 7,
curYear: moment().year(), //当前年
curMonth: moment().month() + 1, //当前月
week: ['一', '二', '三', '四', '五', '六', '七'],
firstDay: moment(`${moment().year()}-${moment().month() + 1}`)
.startOf('month')
.day(), //获取当月第一天是星期几;星期日为 0,星期六为 6
curDays: moment().daysInMonth() //获取当月一共有多少天
};
},
mounted() {
this.getPreMonthDays();
this.getNextMonthDays();
},
methods: {
preMonth() {
this.curMonth--;
// 如果小于1表示上一年;重置日期
if (this.curMonth < 1) {
this.curYear--;
this.curMonth = 12;
}
this.curDays = moment(`${this.curYear}-${this.curMonth}`).daysInMonth();
this.firstDay = moment(`${this.curYear}-${this.curMonth}`).startOf('month').day();
if (this.firstDay == 0) {
this.firstDay = 7;
}
// 显示上个月日期
this.getPreMonthDays();
this.getNextMonthDays();
},
nextMonth() {
this.curMonth++;
// 如果超过12表示下一年;重置日期
if (this.curMonth > 12) {
this.curYear++;
this.curMonth = 1;
}
this.curDays = moment(`${this.curYear}-${this.curMonth}`).daysInMonth();
this.firstDay = moment(`${this.curYear}-${this.curMonth}`).startOf('month').day();
if (this.firstDay == 0) {
this.firstDay = 7;
}
// 显示上个月日期
this.getPreMonthDays();
this.getNextMonthDays();
},
// 获取上个月剩余天数
getPreMonthDays() {
if (this.firstDay == 1) return; //表示上个月无剩余天数
let month = this.curMonth;
let year = this.curYear;
month--;
if (month == 0) {
year--;
month = 12;
}
// 获取上个月的天数
const days = moment(`${year}-${month}`).daysInMonth();
this.preDays = days;
},
// 获取下个月要显示的天数
getNextMonthDays() {
let month = this.curMonth;
let year = this.curYear;
// 获取当月最后一天是星期几
const lastDay = moment(`${year}-${month}`).endOf('month').day();
this.nextDays = lastDay == 0 ? 7 : lastDay;
}
}
};
</script>
<style lang="scss">
.wrap {
width: 700px;
height: 100%;
.weeks {
width: 100%;
height: 50px;
display: flex;
.week {
width: 100px;
line-height: 50px;
text-align: center;
background: gainsboro;
}
}
.days {
display: flex;
flex-wrap: wrap;
.lastday,
.curday {
width: 100px;
line-height: 50px;
text-align: center;
}
.lastday {
color: gold;
}
}
}
</style>
3.日历组件增强版------可选择区间日期
思路:通过clickCount记录点击区间次数,默认是0,点击第一次是1,第二次是2;如果clickCount==2重置clickCount=0
页面渲染:通过判断日期是否在选择区间的最大和最小之间,来更改背景色
相比较之前,更新的代码:
方法新增一个点击事件
selectDate(year, day) {
this.clickCount++;
const date = new Date(`${year}-${this.curMonth}-${day}`);
if (this.clickCount == 1) {
this.startTime = date;
} else if (this.clickCount == 2) {
this.endTime = date;
this.clickCount = 0;
}
if (this.endTime && +this.startTime > +this.endTime) {
[this.startTime, this.endTime] = [this.endTime, this.startTime];
}
// console.log(
// this.clickCount,
// moment(this.startTime).format('YYYY-MM-DD'),
// moment(this.endTime).format('YYYY-MM-DD')
// );
}
computed: {
isSelected() {
return (year, day) => {
const date = new Date(`${year}-${this.curMonth}-${day}`);
return (
(+this.startTime <= +date && +this.endTime >= +date) || +date == +this.startTime || +date == +this.endTime
);
};
}
},
整体代码:
<template>
<div class="wrap">
<el-button @click="preMonth">上个月</el-button>
<el-tag>当前年份{{ curYear }}</el-tag>
<el-tag>当前月份{{ curMonth }}</el-tag>
<el-button @click="nextMonth">下个月</el-button>
<div class="weeks">
<div v-for="item in week" :key="item" class="week">{{ item }}</div>
</div>
<div class="days">
<!-- 上个月 -->
<div
v-for="item in firstDay - 1"
:key="item + 'pre'"
:class="['lastday', { select: isSelected(curYear - 1, preDays - (firstDay - 1 - item)) }]"
@click="selectDate(curYear - 1, preDays - (firstDay - 1 - item))"
>
{{ preDays - (firstDay - 1 - item) }}
</div>
<!-- 当月 -->
<div
v-for="item in curDays"
:key="item + 'cur'"
:class="['curday', { select: isSelected(curYear, item) }]"
@click="selectDate(curYear, item)"
>
{{ item }}
</div>
<!-- 下个月 -->
<div
v-for="item in 7 - nextDays"
:key="item + 'next'"
:class="['lastday', { select: isSelected(curYear + 1, item) }]"
@click="selectDate(curYear + 1, item)"
>
{{ item }}
</div>
</div>
</div>
</template>
<script>
import moment from 'moment';
moment.suppressDeprecationWarnings = true;
export default {
data() {
return {
startTime: null, //记录区间开始时间
endTime: null, //记录区间结束时间
clickCount: 0, //用于记录点击次数
preDays: 30, //上个月天数
nextDays: 7, //下个月天数
curYear: moment().year(), //当前年
curMonth: moment().month() + 1, //当前月
week: ['一', '二', '三', '四', '五', '六', '七'],
firstDay: moment(`${moment().year()}-${moment().month() + 1}`)
.startOf('month')
.day(), //获取当月第一天是星期几;星期日为 0,星期六为 6
curDays: moment().daysInMonth() //获取当月一共有多少天
};
},
computed: {
isSelected() {
return (year, day) => {
const date = new Date(`${year}-${this.curMonth}-${day}`);
return (
(+this.startTime <= +date && +this.endTime >= +date) || +date == +this.startTime || +date == +this.endTime
);
};
}
},
mounted() {
this.getPreMonthDays();
this.getNextMonthDays();
},
methods: {
preMonth() {
this.curMonth--;
// 如果小于1表示上一年;重置日期
if (this.curMonth < 1) {
this.curYear--;
this.curMonth = 12;
}
this.curDays = moment(`${this.curYear}-${this.curMonth}`).daysInMonth();
this.firstDay = moment(`${this.curYear}-${this.curMonth}`).startOf('month').day();
if (this.firstDay == 0) {
this.firstDay = 7;
}
// 显示上个月日期
this.getPreMonthDays();
this.getNextMonthDays();
},
nextMonth() {
this.curMonth++;
// 如果超过12表示下一年;重置日期
if (this.curMonth > 12) {
this.curYear++;
this.curMonth = 1;
}
this.curDays = moment(`${this.curYear}-${this.curMonth}`).daysInMonth();
this.firstDay = moment(`${this.curYear}-${this.curMonth}`).startOf('month').day();
if (this.firstDay == 0) {
this.firstDay = 7;
}
// 显示上个月日期
this.getPreMonthDays();
this.getNextMonthDays();
},
// 获取上个月剩余天数
getPreMonthDays() {
if (this.firstDay == 1) return; //表示上个月无剩余天数
let month = this.curMonth;
let year = this.curYear;
month--;
if (month == 0) {
year--;
month = 12;
}
// 获取上个月的天数
const days = moment(`${year}-${month}`).daysInMonth();
this.preDays = days;
},
// 获取下个月要显示的天数
getNextMonthDays() {
let month = this.curMonth;
let year = this.curYear;
// 获取当月最后一天是星期几
const lastDay = moment(`${year}-${month}`).endOf('month').day();
this.nextDays = lastDay == 0 ? 7 : lastDay;
},
selectDate(year, day) {
this.clickCount++;
const date = new Date(`${year}-${this.curMonth}-${day}`);
if (this.clickCount == 1) {
this.startTime = date;
} else if (this.clickCount == 2) {
this.endTime = date;
this.clickCount = 0;
}
if (this.endTime && +this.startTime > +this.endTime) {
[this.startTime, this.endTime] = [this.endTime, this.startTime];
}
// console.log(
// this.clickCount,
// moment(this.startTime).format('YYYY-MM-DD'),
// moment(this.endTime).format('YYYY-MM-DD')
// );
}
}
};
</script>
<style lang="scss">
.wrap {
width: 700px;
height: 100%;
.weeks {
width: 100%;
height: 50px;
display: flex;
.week {
width: 100px;
line-height: 50px;
text-align: center;
background: gainsboro;
}
}
.days {
display: flex;
flex-wrap: wrap;
.lastday,
.curday {
width: 100px;
line-height: 50px;
text-align: center;
cursor: pointer;
}
.lastday {
color: gold;
}
.select {
background: pink;
color: #fff;
}
}
}
</style>
4.日历组件增强版------可自定义日期内容
未完待续