最近的项目用到了日历组件,但是element的日历组件功能实在是太差了,一些基本的功能都没有,样式也没有接口,想自定义样式比较麻烦,事件还需要用插槽去实现,我就想手写一个组件
我找了好多文章,在这篇文章下拿到了一个完整的日历组件,我又稍微改了一下,实现一个简单的效果
vue手写日历
话不多说,直接上代码
<template>
<div class="page">
<ul class="calendar">
<div
style="
display: flex;
justify-content: space-between;
align-items: center;
"
>
<span
style="font-size: 30px; margin-left: 50px; cursor: pointer"
@click="prevDayclick(1)"
>
<
</span>
<li class="header" style="justify-content: center" >
{
{
currentYear +
"年" +
(currentMonth + 1) +
"月"
}}
</li>
<span
style="font-size: 30px; margin-right: 50px; cursor: pointer"
@click="nextDayclick(1)"
>></span
>
</div>
<li class="week" >
<p >日</p>
<p>一</p>
<p>二</p>
<p>三</p>
<p>四</p>
<p>五</p>
<p>六</p>
</li>
<li class="row day">
<span
@click="prevDayclick(item)"
class="date prevDay"
v-for="item in prevDays"
:key="'A' + item"
>{
{ item }}</span
>
<span
@click="clickdate(item)"
v-for="item in currentDays"
:key="'B' + item"
class="date nowm"
:class="{
jintian: currentDay == item
}"
>{
{ item }}</span
>
<span
@click="nextDayclick(item)"
class="date prevDay"
v-for="item in nextDays"
:key="'A' + item"
>{
{ item }}</span
>
</li>
</ul>
</div>
</template>
<script>
export default {
data () {
return {
week: ['日', '一', '二', '三', '四', '五', '六'],
currentDay: new Date().getDate(),
currentDay2: new Date().getDate(),
currentMonth: new Date().getMonth(),
currentYear: new Date().getFullYear()
}
},
watch: {
currentMonth (newv, oldv) {
if (newv === new Date().getMonth()) {
document.getElementsByClassName('nowm')[this.currentDay2 - 1].style.color = '#3F62AE'
}
}
},
computed: {
currentMonthChinese () {
return new Date(this.currentYear, this.currentMonth).toLocaleString(
'default',
{
month: 'short' }
)
},
currentDays () {
return new Date(this.currentYear, this.currentMonth + 1, 0).getDate()
},
prevDays () {
let data = new Date(this.currentYear, this.currentMonth, 0).getDate()
let num = new Date(this.currentYear, this.currentMonth, 1).getDay()
const days = []
while (num > 0) {
days.push(data--)
num--
}
return days.sort()
},
nextDays () {
const m = this.currentMonth + 1
let num = new Date(this.currentYear, m, 1).getDay()
const days = []
let number = 0
while (num < 7) {
number++
days.push(number)
num++
}
return days.sort()
},
zongdate () {
return this.currentYear + '-' + (this.currentMonth + 1) + '-' + this.currentDay
}
},
methods: {
change () {
this.currentMonth = Number(this.inputVal) - 1
},
clickdate (val) {
this.currentDay = val
if (this.currentMonth === new Date().getMonth() && this.currentDay !== new Date().getDate()) {
document.getElementsByClassName('nowm')[this.currentDay2 - 1].style.color = '#3F62AE'
}
console.log(this.zongdate)
},
prevDayclick (val) {
this.currentDay = val
this.currentMonth = Number(this.currentMonth) - 1
document.getElementsByClassName('nowm')[this.currentDay2 - 1].style.color = 'black'
if (this.currentMonth < 0) {
this.currentMonth = 11
this.currentYear = Number(this.currentYear - 1)
}
console.log(this.zongdate)
},
nextDayclick (val) {
this.currentDay = val
this.currentMonth = Number(this.currentMonth) + 1
document.getElementsByClassName('nowm')[this.currentDay2 - 1].style.color = 'black'
if (this.currentMonth > 11) {
this.currentMonth = 0
this.currentYear = Number(this.currentYear + 1)
}
console.log(this.zongdate)
}
}
}
</script>
<style lang="scss">
.calendar {
width: 500px;
.header {
display: flex;
align-items: center;
height: 64px;
border-radius: 4px 4px 0px 0px;
font-size: 28px;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
color: #404040;
padding-left: 20px;
}
.week {
display: flex;
height: 64px;
background: #fefefe;
font-size: 24px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #404040;
p {
width: 100px;
height: 64px;
}
}
.row {
width: 100%;
display: flex;
justify-content: space-between;
}
.day {
-webkit-box-pack: start;
-ms-flex-pack: start;
justify-content: flex-start;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
span {
width: 100px;
height: 30px;
line-height: 30px;
text-align: center;
}
.date {
display: flex;
align-items: center;
justify-content: center;
width: 71px;
height: 71px;
font-size: 28px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: black;
}
.date:hover {
border-radius: 50%;
background-color: #3f62ae;
color: black!important;;
cursor: pointer;
}
.nowDay {
background: #404040;
}
}
}
.jintian {
border-radius: 50% !important;
background-color: #3f62ae !important;
color: black !important;
}
.prevDay{
color: #ccc!important;
}
</style>