使用vue實現日歷組件的封裝


前言

因項目的需要,而且當前組件庫並不支持業務,所以,重新對日歷組件進行封裝。該篇博客就對實現日歷的思路進行存檔,方便以后的查閱。
先上圖:UI小哥哥的原型圖。接下來的思路都是根據該圖進行解說

邏輯

  • 1.組件的拆分,分出哪些是業務,哪些是基礎組件。
    整體來說,這就是在日歷的基礎上添加業務,所以日歷組件應該是基礎組件,而業務應該是通過插槽插入進去的。那么,右上方的分入分出合計以及每個日歷中的分入,分出都是需要插入的。其余的均是日歷本身的功能。
  • 2.那么接下來,我們先完成日歷組件的封裝,首先,我們要清楚,日歷組件都需要完成哪些功能。功能如下
    • 確定每個月1號對應的是周幾,需要上個月補充幾天,以及下個月補充幾天。
    • 當切換上個月,或者下個月的時候,日歷面板能夠重新渲染。
      emmm...好像就沒啥了 ,重點就是日期的渲染,沒有很大的邏輯問題。也不知道為啥當初看到這個組件的時候 就是不太願意✍

實現步驟

  • 日歷的頭部渲染,即日歷的周一-周日渲染出來。這里使用flex布局即可。
  • 日歷的內容渲染,一個面板上應該是42個元素,包括上個月部分數據,當月整月數據,以及下個月部分數據。需要確定當月1號所在的位置,這樣子,才能知道上個月以及下個月需要補充的天數,
    • 頁面的還原
{{column.label}}
{{item.day}}
``` - 接下來定義每個月對應天數的數組,以及周一-周日日歷頭部的數組。 ``` props: { showYear: { type: Number, default: '' }, showMonth: { type: Number, default: '' } }, data() { return { // 定義每個月對應的天數的數組 daysInMonth: [31, 28, 31,30 , 31, 30, 31,31, 30, 31, 30,31], // 星期的板塊 weekList:[{ label: '周一', value: 1, }, { label: '周二', value: 2, }, { label: '周三', value: 3, }, { label: '周四', value: 4, }, { label: '周五', value: 5, },{ label: '周六', value: 6, }, { label: '周日', value: 7, }] }
 -  下面就需要對日歷面板的數組進行操作了。年,月是從父組件傳入的,當年,月發生改變的時候,日歷面板的數據也隨之發生改變。所以,日歷面板的list通過計算屬性來進行其變更以及頁面的渲染。

totalDayList(val) {
let list = [];
// 定位找到選中月份初始的星期幾
let {showMonth, showYear, daysInMonth} = val;
// 判斷當前是否是閏年
if(showYear%4 ===0 && showYear %100 === 0|| showYear%400 ===0) {
this.daysInMonth[1] =29;
};
// 對月份賦值
let month = showMonth;
// 對年份賦值
let year = showYear;
// 將日期進行拼接,拼接成每月1號的數據
let dateValue = year + '-' + month + '-' + '1';
// 確定當前日期在周幾-0代表的是周日,1代表的是周一。。。。
let currentWeek = new Date(Date.parse(dateValue.replace(/-/g, '/'))).getDay();
// 根據當前日期,判定需要在前面補充幾個日期,在后面補充幾個日期
// 目的是補位:將前一個月的數據進行填充
// 獲取上一個月的天數
let preList = this.preData(month, year,list, currentWeek, daysInMonth);
// 將本月的數據進行渲染
let currentList = this.currentData(daysInMonth, year,month, list);
// 目的是補充后面的位置,保證當前面板的數據完整
let nextList = this.nextData(list, year, month);
list = [...nextList]
return list
}

 - 上個月的數據的渲染

preData(month, year,list, currentWeek, daysInMonth) {
// 獲取上一個月,存在跨年的情況,當當前月份是1月份的時候,上個月是去年的12月
let preMonth = month>1 ? month-1 :12;
// 獲取年份
year = month>1?year:year-1;
// 獲取上個月的天數
let preDays = daysInMonth[preMonth-1];
// 存放的每周對應需要補的天數
let fillNum = [6,0,1,2,3,4,5]
// currentWeek=0,代表是周日,需要上個月補6天
// currentWeek=1, 代表是周一,需要上個月補0天
// currentWeek=2, 代表是周二,需要上個月補1天
// currentWeek=3. 代表是周三,需要上個月補2天
// currentWeek=4, 代表是周四,需要上個月補3天
// currentWeek=5, 代表是周五,需要上個月補4天
// currentWeek=6, 代表是周六,需要上個月補5天
for(let i = preDays; i>preDays-fillNum[currentWeek]; i--) {
let obj = {
type: 'prev',
year,
month: preMonth,
day:i,
className: 'pre_day'
}
list.push(obj);
}
list =list.reverse();
return list;
},

    - 當月的數據渲染

currentData(daysInMonth, year,month, list ) {
// 將本月的數據進行渲染
for(let i=0; i<daysInMonth[month-1];i++) {
let obj = {
year,
day:i+1,
type: 'current',
className: 'current_day',
month,
}
list.push(obj)
}
return list;
},

    - 下個月的數據渲染

nextData(list, year, month) {
// 該日歷面板又42個模塊
let nextNum = 42-list.length;
if(nextNum>0) {
for(let i=0; i<nextNum;i++) {
let obj = {
year,
day: i+1,
type: 'next',
className: 'next_day',
month: month+1
}
list.push(obj)
}
}
return list
}

### 總結:
日歷的邏輯需要注意確定當月1號的位置,以及填充上個月,下個月的數據。記錄一下 自己的邏輯思路。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM