開發那點事(四)vue實現一個日曆插件 開發背景 最終效果 整體思路: 開發細節

開發背景

產品給開發這個流程圖



找了兩天插件,最後產品還是不滿意,自己着手開始實現了,

最終效果

整體思路:

1 確定日期json數組
2 根據數組渲染到頁面上
3 根據不同的status應用不同的css
4 根據不同的狀態做出判斷

開發細節

1 json數組的格式如下

 {
            year: 2019,//年
            month: '02',//月
            dayArray: [
              {
                day: '01', //表示月份中的天
                status: 0 //  0 正常狀態 1最右邊 2 最左邊  3 開始時間 4 結束時間  5正常選中
              }
            ]
          }

要用到了一個函數根據年月獲取月份中的天數

//根據年月獲取天數
function getDate(year, month){
  let d = new Date(year, month, 0);
  return d.getDate();
}

2 數組渲染至頁面

 <div :id="index" v-for="(item,index) in calendarDate">
      <div class="calendar-top row-around">
        <div> {{item.month}}</div>
        <div>{{item.year}}</div>
      </div>
      <div class="calendar-midden">
        <div v-for="preItem in 5" class="day-item column-center">&nbsp;</div>
        <div @click="selectTime(index,dayIndex)" v-for="(dayItem,dayIndex) in item.dayArray"
             class="day-item column-center">
          <!--          status =0正常狀態-->
          <div v-show="dayItem.status ==0" style="width: 100%;height: 100%" class="column-center">{{dayItem.day}}</div>
          <!--          status =1 最右邊-->
          <div v-show="dayItem.status ==1"
               style="width: 100%;height: 100%;background: #91835C;border-bottom-right-radius: 14px;border-top-right-radius:14px"
               class="column-center">
            {{dayItem.day}}
          </div>
          <!--          status =2 最左邊-->
          <div v-show="dayItem.status ==2"
               style="width: 100%;height: 100%;background: #91835C;border-bottom-left-radius: 14px;border-top-left-radius:14px"
               class="column-center">
            {{dayItem.day}}
          </div>
          <!--          status =3 開始-->
          <div v-show="dayItem.status ==3"
               style="float:left;width: 100%;height: 100%;background: #91835C;border-bottom-left-radius: 14px;border-top-left-radius:14px"
               class="column">
            <div
              style="width: 28px;height:28px;background: #F5C509;border-radius: 14px"
              class="column-center">
              {{dayItem.day}}
            </div>
          </div>
          <!--          status =4 結束-->
          <div v-show="dayItem.status ==4"
               style="float: right;width: 100%;height: 100%;background: #91835C;border-bottom-right-radius: 14px;border-top-right-radius:14px"
               class="column-end">
            <div style="margin-left: calc(100% - 28px);width: 28px;height:28px;background: #F5C509;border-radius: 14px"
                 class="column-center">
              {{dayItem.day}}
            </div>
          </div>
          <!--          status =5 正常選中-->
          <div v-show="dayItem.status ==5"
               style="width: 100%;height: 100%;background: #91835C;"
               class="column-center">
            {{dayItem.day}}
          </div>
        </div>
      </div>
      <div class="calendar-bottom"></div>
    </div>

在頁面渲染中status字段判斷比較多,用來區分不同的狀態

3 selectTime判斷選擇時間

向其中傳入數組的兩個index參數,來確定具體的位置,再根據狀態,做出相應的判斷,具體代碼如下

selectTime(index, dayIndex) {
        switch (this.calendarStatus) {
          // 0 默認狀態, 1 選擇了開始時間   2 選擇了結束時間
          case 0:
            let startTime = this.calendarDate[index].year + '-' + (this.calendarDate[index].month) + '-' + (this.calendarDate[index].dayArray[dayIndex].day < 10 ? "0" + this.calendarDate[index].dayArray[dayIndex].day : this.calendarDate[index].dayArray[dayIndex].day);
            if (startTime < this.startDate) {
              this.showToast('選擇時間超出範圍');
              break;
            }
            this.selectStartTime = startTime;
            this.calendarStatus = 1;
            this.calendarDate[index].dayArray[dayIndex].status = 3;

            this.curIndex = index;
            this.curDayIndex = dayIndex;
            break;
          case 1:
            let endTime = this.calendarDate[index].year + '-' + (this.calendarDate[index].month) + '-' + (this.calendarDate[index].dayArray[dayIndex].day < 10 ? "0" + this.calendarDate[index].dayArray[dayIndex].day : this.calendarDate[index].dayArray[dayIndex].day);
            if (endTime < this.selectStartTime) {
              this.showToast('結束時間不能小於開始時間', 'red', 'error');
              return;
            }
            this.setSelectItem(index, dayIndex);
            this.calendarDate[index].dayArray[dayIndex].status = 4;
            this.calendarStatus = 2;
            this.selectEndTime = endTime;
            break;
          case 2:
            this.resetDate();
            this.calendarStatus = 1;
            this.calendarDate[index].dayArray[dayIndex].status = 3;
            this.selectStartTime = this.calendarDate[index].year + '-' + (this.calendarDate[index].month) + '-' + (this.calendarDate[index].dayArray[dayIndex].day < 10 ? "0" + this.calendarDate[index].dayArray[dayIndex].day : this.calendarDate[index].dayArray[dayIndex].day);
            this.curIndex = index;
            this.curDayIndex = dayIndex;
        }

      },

4 獲取時間

通過一個button來輸出選擇的開始時間跟結束時間, 其實在選中結束的時候,就已經設置在變量中了,獲取的時候只需要做出相應的判斷

  //提交時間
      submitTime() {
        let that = this;
        switch (this.calendarStatus) {
          case 0:
            that.showToast('請選擇開始時間');
            break;
          case 1:
            that.showToast('請選擇結束時間');
            break;
          case 2:
            console.log('開始時間:' + that.selectStartTime + ' 結束時間:' + that.selectEndTime);
            that.showToast('開始結束時間已輸出,console');
            break;
        }
      }

5 總結

個人覺得vue最大的特點是數據雙向綁定,而對於開發而言則着重於數組與頁面之間的關係,通過操作數組來控制頁面上數據的改變。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章