手動開發一個日曆組件

前言

應用場景是公司的一個每日推薦專題須要加入日曆功能,點擊日曆能夠跳轉到當日的推薦。vue

設計圖:框架

關於日曆的實現

日曆實現的核心是利用js的Date對象(項目代碼環境是依賴在vue當中)。mvvm

第一步:首頁展現

咱們首先考慮咱們日曆的第一頁,當前月。函數

要展現咱們的當前月,首先咱們須要三個數據:this

  • 當前年份
  • 當前月份
  • 月份下的日期列表

這些數據的初始化(注意這裏只是初始化,由於在日曆的使用過程當中,他們是會隨着交互而變化的)狀態很好得到,前兩個數據咱們只須要經過:spa

this.curdate = new Date();
this.calendarMonth = this.curDate.getMonth() + 1; // 注意月份加1
this.calendarYear = this.curDate.getFullYear();
複製代碼

值得一提的是咱們的日期數據,由於這裏涉及到2個變量,第一個是每月份的天數是不同的。第二個是每月的1號是星期幾也是不固定的(而這個星期幾,則會影響到顯示上,1號應該從哪裏開始)。設計

直接貼上最終的獲取列表的代碼:code

/* 返回當月的日期表 */
getMonthList() {
  // new Date()中的最後一個參數爲0,表示的是當月的最後一天,
  // 所以咱們經過這一句得到的就是傳入的年月的當月最後一天。
  let date = new Date(this.calendarYear, this.calendarMonth, 0);
  // 得到當月的最後一天的日期號,就知道了當月有多少天
  this.days = date.getDate();
  // setDate(1)的做用是把日期變爲當月的第一天
  date.setDate(1);
  // 在經過getDay(),就能知道當月的第一天是星期幾
  let day = date.getDay();
  // 得到1號是星期幾後,在日曆上作一個偏移,這裏我採用的是補0
  let delay = day - 1;
  // 由於星期天在getDay的返回中是0,固特殊處理
  if (day == 0) {
  	delay = 6;
  }
  let list = [];
  for (let i = 0; i < this.days + delay; i++) {
    if (i < delay) {
      list.push(0);
    } else {
      list.push(i - delay + 1)
    }
  }
  return list;
},
// 經過這個函數咱們就得到了當月的列表,格式相似於[0,0,0,1,2,3...31]
複製代碼

第二步:響應變化

變化主要分爲兩個方面:點擊左右箭頭改變月份,點擊具體的日期。cdn

改變月份:

改變月份時咱們要作的主要工做是改變咱們用於記錄時間的變量(使用mvvm框架的好處是咱們不須要關注視圖層面的改變,只須要專一咱們的變量):對象

changeMonth(flag) {
  // flag 記錄左右滑動,對應到月份就是加1和減1
  this.curDate.setMonth(this.calendarMonth - 1 + flag);
  // setNowDate() 函數裏面包括了咱們每次改變日期時所須要作的工做,好比刷新月份列表(即從新調用getMonthList函數等其餘一些功能)
  //若是咱們要把日曆作成一個組件,那麼咱們的函數中確定須要觸發一個事件鉤子以反饋給外部例如:$emit('monthChange')
  this.setNowDate();
},
複製代碼
改變日期:
changeDay(day, el) {
  // 改變個人當前顯示日期
  this.curDate.setDate(day);
  // clickedMonth是用來記錄我當前點擊的月份,這個變量只隨點擊改變,而不隨頁面翻動改變,主要是用來判斷當前日期的樣式用的。
  this.clickedMonth = this.calendarMonth;
  this.clickedYear = this.calendarYear;
  // 獲取當前日曆的推薦數據(具體邏輯不贅述,這裏能夠進行本身須要的操做)
  this.getData(new Date(this.calendarYear, this.calendarMonth - 1, day), true)
  this.setNowDate();
},
複製代碼

點擊了日期後,咱們的樣式也會隨之改變:

// 計算樣式的函數
calDayCls(day) {
  let cls = "calendar-li";
  /* 查看當前 */
  if (day == this.calendarDay && this.calendarYear == this.clickedYear && this.calendarMonth == this.clickedMonth) {
    cls += ' calendar-li-active';
  }
  return cls
}
複製代碼

至此,咱們的日曆的核心功能就完成了,核心函數以下:

setNowDate // 改變控制當前日曆顯示的變量
changeMonth // 改變月份
getMonthList // 獲取月份日期表
changeDay // 改變日期
calDayCls // 計算當前日期的樣式
複製代碼

有了這些核心部分,就基本實現了日曆的核心功能,而後就能夠在上面添加更多的自定義的功能了,由於不少是涉及到我本身項目中個性化的東西,不具有過多參考價值,固沒有在代碼體現。

相關文章
相關標籤/搜索