基于vue手動(dòng)實(shí)現(xiàn)一個(gè)日歷組件
最近需要一個(gè)日歷,當(dāng)前能用的現(xiàn)成的組件庫(kù)也有日歷組件,但因?yàn)椴粷M(mǎn)足需求,所以決定自己搞一個(gè)。
最終效果:

實(shí)現(xiàn)的功能:上個(gè)月、當(dāng)月、下個(gè)月和回到今天切換功能。
對(duì)應(yīng)的html部分
<div class="plan-zone">
<div class="btn-group">
<div class="left-btn">
<el-button-group>
<el-button @click="prevMonth" type="primary"
>上一個(gè)月</el-button
>
<el-button type="primary" @click="goToCurrentMonth">{{
getCurDate()
}}</el-button>
<el-button @click="nextMonth" type="primary"
>下一個(gè)月</el-button
>
</el-button-group>
<el-button type="primary" @click="goToCurrentDay"
>回到今天</el-button
>
</div>
<div class="right-btn">
<button class="new">新安排</button>
<button class="ing">進(jìn)行中</button>
<button class="finish">已完成</button>
</div>
</div>
<!-- <el-calendar v-model="value"> </el-calendar> -->
<table class="parent-table">
<thead>
<th>周一</th>
<th>周二</th>
<th>周三</th>
<th>周四</th>
<th>周五</th>
<th>周六</th>
<th>周日</th>
</thead>
<tbody>
<tr v-for="(week, windex) in weeks" :key="windex">
<td
v-for="(day, dindex) in week"
:class="{ highlight: isToday(day.date) }"
:key="dindex"
>
<div
class="content"
:class="{
faded: !isCurrentMonth(day.date),
}"
>
<div class="top-day">{{ day.date.getDate() }}日</div>
<div class="middle-event"></div>
<div class="bottom-event"></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
對(duì)應(yīng)scss部分
.faded {
opacity: 0.3;
}
.highlight {
background: rgba(255, 220, 40, 0.15);
}
.plan-zone {
margin-top: 10px;
.btn-group {
display: flex;
justify-content: space-between;
.right-btn {
button.new {
background-color: #fff;
border: 1px solid #fff;
color: #409eef;
position: relative;
&::before {
content: "";
width: 8px;
height: 8px;
border-radius: 50%;
position: absolute;
top: 7px;
left: -3px;
background-color: #409eef;
}
}
button.ing {
background-color: #fff;
border: 1px solid #fff;
color: #ff974a;
position: relative;
&::before {
content: "";
width: 8px;
height: 8px;
border-radius: 50%;
position: absolute;
top: 7px;
left: -3px;
background-color: #ff974a;
}
}
button.finish {
background-color: #fff;
border: 1px solid #fff;
color: #3dd599;
position: relative;
&::before {
content: "";
width: 8px;
height: 8px;
border-radius: 50%;
position: absolute;
top: 7px;
left: -3px;
background-color: #3dd599;
}
}
}
}
}
.parent-table {
border-collapse: collapse;
table-layout: fixed;
width: 100%;
margin-top: 20px;
th,
td {
width: 14.4%;
border: 1px solid #ddd;
}
td {
padding: 2px 3px;
.content {
position: relative;
min-height: 80px;
}
vertical-align: top;
.top-day {
text-align: right;
font-size: 13px;
}
}
}
.table-date {
display: flex;
> div {
flex: 1;
}
}對(duì)應(yīng)的JavaScript部分
export default {
data() {
return {
current: new Date(),
today: new Date(),
};
},
computed: {
weeks() {
return this.getMonthData(
this.current.getFullYear(),
this.current.getMonth() + 1
);
},
},
methods: {
getCurDate() {
var date = new Date();
var year = date.getFullYear();
var month = date.getMonth() + 1; // getMonth() returns a zero-based value (0-11)
if (month < 10) {
month = "0" + month; // add a leading zero if the month is a single digit
}
return year + "-" + month;
},
isToday(date) {
let today = new Date();
return (
date.getDate() === today.getDate() &&
date.getMonth() === today.getMonth() &&
date.getFullYear() === today.getFullYear()
);
},
goToCurrentDay() {
this.current = new Date(this.today);
},
isCurrentMonth(date) {
return date.getMonth() === this.current.getMonth();
},
prevMonth() {
this.current.setMonth(this.current.getMonth() - 1);
this.current = new Date(this.current);
// console.log(this.current.getFullYear(), 'dedede')
},
nextMonth() {
this.current.setMonth(this.current.getMonth() + 1);
this.current = new Date(this.current);
},
goToCurrentMonth() {
this.current = new Date(this.today);
},
getMonthData(year, month) {
let weeks = [];
let firstDay = new Date(year, month - 1, 1); // 這個(gè)月的第一天
let lastDayOfCurrentMonth = new Date(year, month, 0); // 這個(gè)月的最后一天
let lastDayOfPrevMonth = new Date(year, month - 1, 0); // 上個(gè)月的最后一天
//這里的0有一個(gè)特殊的意義,它可以返回上個(gè)月的最后一天。也就是說(shuō),如果你想知道某個(gè)月有多少天,你可以創(chuàng)建一個(gè)日期對(duì)象,年份和月份設(shè)置為你想知道的月份,日期設(shè)置為0,然后調(diào)用getDate()方法,返回的就是那個(gè)月的天數(shù)。
// new Date(year, month - 1, 0) 最后一個(gè)參數(shù),超過(guò)當(dāng)月天數(shù)重新排序,比如1月31天,最后一個(gè)參數(shù)為33返回2
let startDayOfWeek = firstDay.getDay() === 0 ? 7 : firstDay.getDay(); // 開(kāi)始是周幾
let dayCount = 1; // 當(dāng)前日期的變量,初始值為1
// 上一個(gè)月的天數(shù)
let prevMonthDayCount = lastDayOfPrevMonth.getDate() - startDayOfWeek + 2; // 這是為了在日歷中填充上個(gè)月的日期。
// console.log(lastDayOfPrevMonth.getDate(), startDayOfWeek, prevMonthDayCount)
for (let i = 0; i < 6; i++) {
let week = [];
for (let j = 0; j < 7; j++) {
// 日期為上個(gè)月的日期,然后將這個(gè)日期對(duì)象添加到`week`數(shù)組中,同時(shí)`prevMonthDayCount`加1。
if (i === 0 && j < startDayOfWeek - 1) {
week.push({ date: new Date(year, month - 2, prevMonthDayCount++) });
// 日期為下個(gè)月的日期,然后將這個(gè)日期對(duì)象添加到`week`數(shù)組中,同時(shí)`dayCount`加1
} else if (dayCount > lastDayOfCurrentMonth.getDate()) {
week.push({
date: new Date(
year,
month,
dayCount++ - lastDayOfCurrentMonth.getDate()
),
});
// 日期為這個(gè)月的日期,然后將這個(gè)日期對(duì)象添加到`week`數(shù)組中,同時(shí)`dayCount`加1
} else {
week.push({ date: new Date(year, month - 1, dayCount++) });
}
}
weeks.push(week);
}
return weeks;
}
},
};
關(guān)鍵是上面的getMonthData方法。理解這個(gè)方法就理解了這個(gè)組件。
以上就是基于vue手動(dòng)實(shí)現(xiàn)一個(gè)日歷組件的詳細(xì)內(nèi)容,更多關(guān)于vue日歷組件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Vue使用Cropper實(shí)現(xiàn)圖片裁剪功能
圖片裁剪功能無(wú)論是用戶(hù)頭像的裁剪,還是圖片內(nèi)容的精確調(diào)整,都成為了提升用戶(hù)體驗(yàn)的關(guān)鍵一環(huán),本文將詳細(xì)介紹如何在Vue.js項(xiàng)目中集成并使用Cropper.js實(shí)現(xiàn)一個(gè)強(qiáng)大的圖片裁剪組件,需要的可以參考下2024-11-11
Vue3造輪子之Typescript配置highlight過(guò)程
這篇文章主要介紹了Vue3造輪子之Typescript配置highlight過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07
vue中的模態(tài)對(duì)話(huà)框組件實(shí)現(xiàn)過(guò)程
這篇文章主要介紹了vue中的模態(tài)對(duì)話(huà)框組件實(shí)現(xiàn)過(guò)程,通過(guò)template定義組件,并添加相應(yīng)的對(duì)話(huà)框樣式,需要的朋友可以參考下2018-05-05
Vue3實(shí)現(xiàn)自定義Input組件的示例詳解
這篇文章主要為大家詳細(xì)介紹了如何使用Vue3自定義實(shí)現(xiàn)一個(gè)類(lèi)似el-input的組件,可以v-model雙向綁定,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03
Vue + Element-ui的下拉框el-select獲取額外參數(shù)詳解
這篇文章主要介紹了Vue + Element-ui的下拉框el-select獲取額外參數(shù)詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08
vue中formdata傳值給后臺(tái)時(shí)參數(shù)為空的問(wèn)題
這篇文章主要介紹了vue中formdata傳值給后臺(tái)時(shí)參數(shù)為空的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06

