日曆日程安排表格calendar

自定義vue日曆組件,可用於日程安排,人員分工

組件:引用了moment插件和iview的日期選擇組件

<template>
  <div class="canlendar-container">
    <div class="time-selector">
      <slot name="otherOperate"></slot>

      <Button @click="getNow">定位今日</Button> &nbsp;
      <Button @click="getBefore">&lt; 上月</Button> &nbsp;
      <DatePicker
        type="month"
        placeholder="選擇年月"
        v-model="nowDate"
        @on-change="changeUpdate"
      ></DatePicker>
      &nbsp; <Button @click="getBehind">下月 &gt;</Button> &nbsp;
      <span> &nbsp; 當前時間:{{ `${dateObj.year}年${dateObj.month}月` }}</span>

      <slot name="rightOperate"></slot>
    </div>

    <div class="canlendar-content">
      <ul class="canlendar-header">
        <li
          class="item"
          v-for="(t, i) in weeks"
          :class="i === 5 || i === 6 ? 'weekend' : ''"
          :key="t"
        >
          {{ t }}
        </li>
      </ul>
      <ul class="canlendar-body">
        <Spin fix v-show="loading"></Spin>
        <li v-for="(t, i) in dateList" :key="i" class="item">
          <div
            v-for="(tt, ii) in t"
            class="date-item"
            :class="{
              active: tt.fullDate === today.fullDate,
              cursor: tt.date,
              disabled:
                (tt.isSelling === undefined && tt.date) || tt.isSelling === 0
            }"
            :key="`${tt.day}${ii}`"
            @click="clickItem(i, ii, tt)"
          >
            <slot name="dataInfo" :text="tt"></slot>
          </div>
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
import moment from "moment";
// 日曆渲染的功能代碼,無業務代碼
export default {
  name: "myCanlendar",
  props: {
    getCanlendarDate: {
      type: Function,
      default() {}
    },
    queryData: {
      type: Function,
      default() {}
    }
  },
  data() {
    return {
      loading: false,
      today: {},
      dateObj: {},
      weeks: ["週一", "週二", "週三", "週四", "週五", "週六", "週日"],
      dateList: [],
      nowDate: ""
    };
  },
  mounted() {
    this.initToday();
    this.initCanlender();
  },
  methods: {
    initToday() {
      this.today = this.getDateObj();
    },
    initCanlender(date) {
      this.dateList = [];
      this.dateObj = this.getDateObj(date);
      this.nowDate = this.dateObj.year + "年" + this.dateObj.month + "月";
      //   月初月末
      let firstDay = new Date(this.dateObj.year, this.dateObj.month - 1, 1);
      let lastDay = new Date(this.dateObj.year, this.dateObj.month, 0);
      //   一個月的天數
      let days = (lastDay - firstDay) / 86400000 + 1;
      //   月初日期爲周幾
      let flagDay = firstDay.getDay() === 0 ? 7 : firstDay.getDay();
      //   計算第一週和剩下的幾周,得到一個月的週數
      //   除了第一週,剩下的日期數
      let firstWeekDayNum = this.weeks.length - flagDay + 1;
      let leftDays = days - firstWeekDayNum;
      let weekNum = 1 + Math.ceil(leftDays / this.weeks.length);
      let nullObj = {
        date: null,
        year: null,
        month: null,
        day: null
      };
      //   循環獲取日曆的數據
      for (let i = 0; i < weekNum; i++) {
        let arr = [];
        if (i === 0) {
          for (let j = 1; j <= this.weeks.length; j++) {
            if (j >= flagDay) {
              let trueDate = firstWeekDayNum - (this.weeks.length - j);
              arr.push(this.getCanlendarDate(trueDate, this.dateObj));
            } else {
              arr.push({ ...nullObj });
            }
          }
        } else {
          let startDay = firstWeekDayNum + 1 + this.weeks.length * (i - 1);
          for (let j = startDay; j < startDay + 7; j++) {
            if (j >= days + 1) {
              arr.push({ ...nullObj });
            } else {
              arr.push(this.getCanlendarDate(j, this.dateObj));
            }
          }
        }
        this.dateList.push(arr);
      }
      this.$emit("after-render", {
        list: this.dateList,
        dateObj: this.dateObj
      });
      this.queryData();
    },
    getDateObj(date) {
      let getDate = date ? new Date(date) : new Date();
      let year = getDate.getFullYear();
      let month = getDate.getMonth() + 1;
      let day = getDate.getDate();
      return {
        fullDate: moment(new Date(`${year}-${month}-${day}`)).format(
          "YYYY-MM-DD"
        ),
        date: getDate,
        year: year,
        month: month,
        day: day,
        week: getDate.getDay(),
        // 月初的日期
        firstDay: moment(new Date(year, month - 1, 1)).format("YYYY-MM-DD"),
        // 月末的日期
        lastDay: moment(new Date(year, month, 0)).format("YYYY-MM-DD")
      };
    },
    clickItem(index1, index2, item) {
      if (item.date) {
        this.$emit("select-item", {
          index1: index1,
          index2: index2
        });
      }
    },
    getNow() {
      this.initCanlender();
    },
    getBefore() {
      if (this.dateObj.month - 1 > 0) {
        this.initCanlender(`${this.dateObj.year}-${this.dateObj.month - 1}`);
      } else {
        this.initCanlender(`${this.dateObj.year - 1}-12`);
      }
    },
    changeUpdate(date) {
      this.initCanlender(date);
    },
    getBehind() {
      if (this.dateObj.month + 1 <= 12) {
        this.initCanlender(`${this.dateObj.year}-${this.dateObj.month + 1}`);
      } else {
        this.initCanlender(`${this.dateObj.year + 1}-1`);
      }
    }
  }
};
</script>

<style lang="less" scoped>
@borderColor: #ccc;
@dateHeight: 80px;
ul,
li {
  list-style: none;
}
.canlendar-container {
  .time-selector {
    position: relative;
    text-align: center;
    margin-bottom: 15px;
    .set-multi {
      position: absolute;
      left: 0;
    }
    .clear-multi {
      position: absolute;
      right: 0;
    }
  }
  .canlendar-content {
    border: 1px solid @borderColor;
    .canlendar-header {
      border-bottom: 1px solid @borderColor;
      .item {
        display: inline-block;
        text-align: center;
        width: calc(~"100% / 7");
        padding: 18px 0;
        border-right: 1px solid @borderColor;
        background: #2fafff;
        font-size: 13px;
        color: #fff;
        letter-spacing: 1px;
        &.weekend {
          color: #666;
          background: #ffeb3b;
        }
        &:last-child {
          border-right: none;
        }
      }
    }
    .canlendar-body {
      position: relative;
      overflow: hidden;
      .item {
        float: left;
        width: 100%;
        border-bottom: 1px solid @borderColor;
        &:last-child {
          border-bottom: none;
        }
        .date-item {
          float: left;
          height: @dateHeight;
          box-sizing: border-box;
          padding: 5px 0;
          width: calc(~"100% / 7");
          text-align: center;
          border-right: 1px solid @borderColor;
          font-size: 13px;
          color: #666;
          .date-info {
            overflow: hidden;
            .date-number {
              font-weight: bold;
              width: 30px;
              float: left;
            }
            .sold-out {
              color: #f30;
            }
            .on-sell {
              color: #2fafff;
            }
            .soldBtn {
              margin-right: 30px;
              float: left;
              width: calc(100% - 60px);
            }
          }
          &:last-child {
            border-right: none;
          }
          &.active {
            background: #f90 !important;
          }
          &.cursor {
            cursor: pointer;
          }
          &.disabled {
            background: #e5e5e5;
          }
        }
      }
    }
  }
}
</style>

使用:先引入上面的組件再使用

  <canlendar
      :getCanlendarDate="getCanlendarDate"
      :queryData="queryData"
      @select-item="toSelectDate"
      @after-render="getDateList"
    >
      <Button
        class="set-multi"
        type="info"
        @click="setMulti"
        slot="otherOperate"
        >批量設置</Button
      >
      <div slot="dataInfo" slot-scope="props">
        
        <p class="date-info" v-if="props.text.date">
          ¥{{ props.text.costPrice }}
        </p>
        <p v-else>
          暫無價格信息
        </p>
        
      </div>
    </canlendar>



    methods:
    // 每個日曆對象數據
    getCanlendarDate(trueDate, dateObj) {
      let fullDate = new Date(`${dateObj.year}-${dateObj.month}-${trueDate}`);
      return {
        productId: "",
        productName: "",
        fullDate: moment(fullDate).format("YYYY-MM-DD"),
        date: fullDate,
        year: dateObj.year,
        month: dateObj.month,
        day: trueDate, // 日期
        orderedCount: 0, // 已預定數
      };
    },
    //獲取後端接口數據
    queryData() {}

效果如下:

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