美文网首页
vue-elementUi-Calendar前端日历插件折腾记

vue-elementUi-Calendar前端日历插件折腾记

作者: 郝艳峰Vip | 来源:发表于2018-11-02 17:01 被阅读0次

    写在前面

    最近好不容易闲了下来,把之前写的vue的日历总结一下,贴出来,过程中深刻的理解到做事情一定要趁热打铁,速战速决,不要拖拖拉拉,否则不仅仅是自己就忘记了,而且很影响效率。不过重要的还是好记性不如烂笔头,写过的东西一定要记下来。

    今天把之前写的一个功能记录下来,vue+element-ui的日历,之前写的时候也是趟了很多坑,不过最终搞定了,幸好幸好。现在把代码和思路贴出来,方便以后学习,更新,使用。也希望可以帮助到更多的小伙伴们。

    Step一:新建一个公共的文件夹,用来放公共的组件,在这我起名为CalendarHome///////里边有三个文件分别是eventCard.vue,header.vue,fullCalendar.vue.

    首先介绍下:eventCard.vue,里边主要放的是日历里边的日程提醒显示的事件,主要用到的vue-slot插槽。

    其中的moment.js为js的日期处理类库详情请看moment.js 官网

     <template>
        <p class="event-item" :class="cssClasses"
           @click="$emit('click', event, $event)">
            <slot :event="event" v-if="showTitle">
                Def: {{ event.title }}
            </slot>
        </p>
    </template>
    
    <script>
        import moment from 'moment'
        export default {
            props: ['event', 'date', 'firstDay'],
            computed: {
                cssClasses () {
                    let cssClasses = this.event.cssClass;
    
                    if (!Array.isArray(cssClasses)) {
                        cssClasses = [cssClasses];
                    } else {
                        cssClasses = Array.from(cssClasses);
                    }
    
                    if (this.start.isSame(this.date, 'day')) {
                        cssClasses.push('is-start');
                    }
    
                    if (this.end.isSame(this.date, 'day')) {
                        cssClasses.push('is-end');
                    }
    
                    if (! this.event.isShow) {
                        cssClasses.push('is-opacity');
                    }
    
                    return cssClasses.join(' ');
                },
                showTitle() {
                    return (this.date.day() == this.firstDay || this.start.isSame(this.date, 'day'));
                },
                start () {
                    return moment(this.event.start);
                },
                end () {
                    return moment(this.event.end);
                }
            }
        }
    </script>
    
    再者介绍下:header.vue,里边主要放的是日历头部的显示,下拉框,左右箭头事件,同样也是用到的vue-slot插槽。
    <template>
      <div class="full-calendar-header">
        <div class="header-left">
          <slot name="header-left">
          </slot>
        </div>
        <div class="header-center">
          <span class="prev-month iconfont icon-fanhui"
                @click.stop="goPrev"></span>
          <!-- <span class="title">{{title}}</span> -->
          <el-select v-model="value"
                     @change="changeselectYear" style="width:100px;">
            <el-option v-for="item in options"
                       :key="item.value"
                       :label="item.label"
                       :value="item.value" >
            </el-option>
          </el-select>
          <el-select v-model="value1" @change="changeselectMonth"  style="width:100px;">
            <el-option v-for="item in options1"
                       :key="item.value"
                       :label="item.label"
                       :value="item.value">
            </el-option>
          </el-select>
          <span class="next-month iconfont icon-gengduo"
                @click.stop="goNext"></span>
        </div>
        <div class="StateThree">
          <!-- <div class="CircleData FirstGreen"></div>
          <div class="StateFirst">数据完整</div>
          <div class="CircleData FirstYellow"></div>
          <div class="StateSecond">数据残缺</div> -->
        </div>
        <div class="header-right">
          <slot name="header-right">
          </slot>
        </div>
      </div>
    </template>
    <script>
    // import dateFunc from './dateFunc'
    import moment from "moment";
    
    export default {
      props: {
        currentMonth: {},
        titleFormat: {},
        firstDay: {},
        monthNames: {},
        locale: {}
      },
      data() {
        return {
          leftArrow: "<",
          rightArrow: ">",
          options: [],
          options1: [
            {
              value: "01月",
              label: "01月"
            },
                {
              value: "02月",
              label: "02月"
            },
                {
              value: "03月",
              label: "03月"
            },
                {
              value: "04月",
              label: "04月"
            },    {
              value: "05月",
              label: "05月"
            },
                {
              value: "06月",
              label: "06月"
            },
                {
              value: "07月",
              label: "07月"
            },
                {
              value: "08月",
              label: "08月"
            },
                {
              value: "09月",
              label: "09月"
            },
                {
              value: "10月",
              label: "10月"
            },
                {
              value: "11月",
              label: "11月"
            },
              {
              value: "12月",
              label: "12月"
            }
          ],
          value: "",
          value1: ""
        };
      },
      mounted() {
        this.changetitle();
        this.changYear();
      },
      computed: {
        title() {
          if (!this.currentMonth) return;
          return this.currentMonth.locale(this.locale).format("YYYY" + "年" + "MM" + "月");
        },
      },
      methods: {
        changetitle() {
          this.value = this.title.substring(0, 5);
          this.value1 = this.title.substring(5, 8);
        },
        changYear() {
          let YearArray = [];
          for (var i = 1901; i <= 2100; i++) {
          let YearJson = {};
             YearJson.value = i + "年";
             YearJson.lable = i + "年";
             YearArray.push(YearJson);
          }
          this.options = YearArray;
        },
        goPrev() {
          var newMonth = moment(this.currentMonth).subtract(1, "months").startOf("month");
          this.$emit("change", newMonth);
          /*setTimeout(() => {
          this.changetitle();
          }, 1);*/
          this.value =  newMonth.format("YYYY" + "年" + "MM"+ '月' + 'DD').substring(0, 5)
          this.value1 =  newMonth.format("YYYY" + "年" + "MM"+ '月' + 'DD').substring(5, 8)
        },
        goNext() {
          var newMonth = moment(this.currentMonth).add(1, "months").startOf("month");
          this.$emit("change", newMonth);
          /*setTimeout(() => {
          this.changetitle();
          }, 1);*/
          this.value =  newMonth.format("YYYY" + "年" + "MM"+ '月' + 'DD').substring(0, 5)
          this.value1 =  newMonth.format("YYYY" + "年" + "MM"+ '月' + 'DD').substring(5, 8)
        },
        changeselectYear(val) {
          let nowTime = val + this.value1;
          var moment123 = moment(nowTime,'YYYY-MM-DD HH:mm:ss');
          this.$emit("change", moment123);
        },
        changeselectMonth(val){
          let nowTime = this.value + val;
          var moment123 = moment(nowTime,'YYYY-MM-DD HH:mm:ss');
          this.$emit("change", moment123);
        }
      }
    };
    </script>
    <style lang="scss">
    .full-calendar-header {
      display: flex;
      align-items: center;
      flex-direction: column;
      .header-left,
      .header-right {
        flex: 0;
      }
      .header-center {
        flex: 3;
        width: 100%;
        height: 30px;
        line-height: 30px;
        text-align: center;
        flex-direction: column;
        align-items: center;
        .title {
          margin: 0 10px;
          font-size: 22px;
          font-weight: bold;
          color: #797979;
        }
        .prev-month,
        .next-month {
          cursor: pointer;
        }
        .prev-month {
          float: left;
          margin-left: 40px;
        }
        .next-month {
          float: right;
          margin-right: 40px;
        }
      }
      .StateThree {
        width: 100%;
        height: 40px;
        display: flex;
        // flex-direction: row-reverse;
        justify-content: flex-end;
        align-items: center;
        div {
          margin: 0px 5px;
        }
        .FirstGreen {
          background: #accf81;
        }
        .FirstYellow {
          background: #f9a101;
        }
        .CircleData {
          width: 8px;
          height: 8px;
          border-radius: 100%;
        }
      }
    }
    </style>
    
    最后介绍下:fullCalendar.vue.,里边主要放的日历的主体部分,以及接受外部事件以及参数的接口,还有暴漏出去的接口。
    <template>
      <div class="comp-full-calendar">
        <!-- header pick month -->
        <fc-header :current-month="currentMonth"
          :first-day="firstDay"
          :locale="locale"
          @change="emitChangeMonth">
    
          <div slot="header-left">
            <slot name="fc-header-left">
            </slot>
          </div>
    
          <div slot="header-right">
            <slot name="fc-header-right">
            </slot>
          </div>
        </fc-header>
        <!-- body display date day and events -->
        <div class="full-calendar-body">
          <!-- 上方显示的星期显示表 -->
          <div class="weeks">
            <span class="week" v-for="dayIndex in 7" :class="{'isBgray': dayIndex == 1 || dayIndex == 7}">{{ (dayIndex - 1) | localeWeekDay(firstDay, locale) }}</span>
          </div>
          <div class="dates" ref="dates">
            <div class="dates-bg">
              <div class="week-row" v-for="week in currentDates">
                <div class="day-cell" v-for="day in week" :class="{'isBgray': day.weekDay == 0 || day.weekDay == 6}">
                  <span class="CircleData FirstGreen"></span>
            
                  <p class="day-number"   :class="{'today' : day.isToday,
                  'not-cur-month' : !day.isCurMonth,'isCgray' : day.weekDay == 0 || day.weekDay == 6}">{{ day.monthDay }}</p>
            
                </div>
              </div>
            </div>
    
            <!-- absolute so we can make dynamic td -->
            <div class="dates-events">
              <div class="events-week" v-for="week in currentDates">
                <div class="events-day" v-for="day in week" track-by="$index"
                     @click.stop="dayClick(day.date, $event)" @mouseenter="Dayenter(day.date, $event)" @mouseleave="Dayleave(day.date, $event)">
                    <span class="CircleData FirstGreen"></span>
                  <p class="day-number"  :class="{'today' : day.isToday,
                  'not-cur-month' : !day.isCurMonth,'isCgray' : day.weekDay == 0 || day.weekDay == 6}">{{day.monthDay}}</p>
                <!-- 事件的显示框 -->
                  <div class="event-box">
                    <event-card :event="event" :date="day.date" :firstDay="firstDay" v-for="event in day.events" v-show="event.cellIndex <= eventLimit" @click="eventClick" :key="event">
                      <template slot-scope="p">
                        <slot name="fc-event-card" :event="p.event"></slot>
                      </template>
                    </event-card>
                    <p v-if="day.events.length > eventLimit"
                       class="more-link" @click.stop="selectThisDay(day, $event)">
                      + {{day.events[day.events.length -1].cellIndex - eventLimit}} more
                    </p>
                  </div>
                  <!-- 右侧的显示框 -->
                <div id="RightAlert">
                  <div id="Triangle"></div>
                  <div id="DeleteTop" @click.stop="deletetip($event)"></div>
                </div>
                </div>
              </div>
            </div>
    
            <!-- full events when click show more -->
            <div class="more-events" v-show="showMore"
                 :style="{left: morePos.left + 'px', top: morePos.top + 'px'}">
              <div class="more-header">
                <span class="title">{{ moreTitle(selectDay.date) }}</span>
                <span class="close" @click.stop="showMore = false">x</span>
              </div>
              <div class="more-body">
                <ul class="body-list">
                  <li v-for="event in selectDay.events"
                      v-show="event.isShow" class="body-item"
                      @click="eventClick(event, $event)">
                    {{event.title}}
                  </li>
                </ul>
              </div>
            </div>
    
            <slot name="body-card">
    
            </slot>
    
          </div>
        </div>
      </div>
    </template>
    <script >
    import moment from "moment";
    import EventCard from "./components/eventCard.vue";
    
    let dateFunc = {
      getMonthViewStartDate (date, firstDay) {
        firstDay = parseInt(firstDay);
        let start = moment(date);
        let startOfMonth = moment(start.startOf('month'));
    
        start.subtract(startOfMonth.day(), 'days');
    
        if (startOfMonth.day() < firstDay) {
          start.subtract(7, 'days');
        }
    
        start.add(firstDay, 'days');
    
        return start;
      },
      getMonthViewEndDate (date) {
        return this.getMonthViewStartDate().add(6, 'weeks');
      }
    };
    
    
    export default {
      props: {
        events: {
          // events will be displayed on calendar
          type: Array,
          default: []
        },
        locale: {
          type: String,
          default: "zh"
        },
        firstDay: {
          type: Number | String,
          validator(val) {
            let res = parseInt(val);
            return res >= 0 && res <= 6;
          },
          default: 0,
          lang:{
            type:String,
            default:"zh"
          }
        }
      },
      components: {
        "event-card": EventCard,
        "fc-header": require("./components/header").default
      },
      mounted() {
        this.emitChangeMonth(this.currentMonth);
      },
      data() {
        return {
          currentMonth: moment().startOf("month"),
          isLismit: true,
          eventLimit: 3,
          showMore: false,
          morePos: {
            top: 0,
            left: 0
          },
          selectDay: {}
        };
      },
      computed: {
        currentDates() {
          return this.getCalendar();
        }
      },
      methods: {
        deletetip(jsevent){
          console.log(jsevent.target.parentNode);
          jsevent.target.parentNode.style.display = 'none';
        },
        emitChangeMonth(firstDayOfMonth) {
          this.currentMonth = firstDayOfMonth;
    
          let start = dateFunc.getMonthViewStartDate(
            firstDayOfMonth,
            this.firstDay
          );
          let end = dateFunc.getMonthViewEndDate(firstDayOfMonth, this.firstDay);
    
          this.$emit("changeMonth", start, end, firstDayOfMonth);
        },
        moreTitle(date) {
          if (!date) return "";
          return moment(date).format("ll");
        },
        getCalendar() {
          // calculate 2d-array of each month
          let monthViewStartDate = dateFunc.getMonthViewStartDate(
            this.currentMonth,
            this.firstDay
          );
          let calendar = [];
    
          for (let perWeek = 0; perWeek < 6; perWeek++) {
            let week = [];
    
            for (let perDay = 0; perDay < 7; perDay++) {
              week.push({
                monthDay: monthViewStartDate.date(),
                isToday: monthViewStartDate.isSame(moment(), "day"),
                isCurMonth: monthViewStartDate.isSame(this.currentMonth, "month"),
                weekDay: perDay,
                date: moment(monthViewStartDate),
                events: this.slotEvents(monthViewStartDate)
              });
    
              monthViewStartDate.add(1, "day");
            }
    
            calendar.push(week);
          }
    
          return calendar;
        },
        slotEvents(date) {
          // find all events start from this date
          let cellIndexArr = [];
          let thisDayEvents = this.events.filter(day => {
            let st = moment(day.start);
            let ed = moment(day.end ? day.end : st);
    
            return date.isBetween(st, ed, null, "[]");
          });
    
          // sort by duration
          thisDayEvents.sort((a, b) => {
            if (!a.cellIndex) return 1;
            if (!b.cellIndex) return -1;
            return a.cellIndex - b.cellIndex;
          });
    
          // mark cellIndex and place holder
          for (let i = 0; i < thisDayEvents.length; i++) {
            thisDayEvents[i].cellIndex = thisDayEvents[i].cellIndex || i + 1;
            thisDayEvents[i].isShow = true;
            if (thisDayEvents[i].cellIndex == i + 1 || i > 2) continue;
            thisDayEvents.splice(i, 0, {
              title: "holder",
              cellIndex: i + 1,
              start: date.format(),
              end: date.format(),
              isShow: false
            });
          }
    
          return thisDayEvents;
        },
        selectThisDay(day, jsEvent) {
          this.selectDay = day;
          this.showMore = true;
          this.morePos = this.computePos(event.target);
          this.morePos.top -= 100;
          let events = day.events.filter(item => {
            return item.isShow == true;
          });
          this.$emit("moreClick", day.date, events, jsEvent);
        },
        computePos(target) {
          let eventRect = target.getBoundingClientRect();
          let pageRect = this.$refs.dates.getBoundingClientRect();
          return {
            left: eventRect.left - pageRect.left,
            top: eventRect.top + eventRect.height - pageRect.top
          };
        },
        dayClick(day, jsEvent) {
          this.$emit("dayClick", day, jsEvent);
        },
        Dayenter(day, jsEvent){
          this.$emit("DayenterFather", day, jsEvent);
        },
          Dayleave(day, jsEvent){
          this.$emit("DayleaveFather", day, jsEvent);
        },
        eventClick(event, jsEvent) {
          if (!event.isShow) return;
    
          jsEvent.stopPropagation();
          let pos = this.computePos(jsEvent.target);
          this.$emit("eventClick", event, jsEvent, pos);
        }
      },
      filters: {
        localeWeekDay(weekday, firstDay, locale) {
          firstDay = parseInt(firstDay);
          const localMoment = moment().locale(locale);
          return localMoment.localeData().weekdaysShort()[(weekday + firstDay) % 7];
        }
      }
    };
    </script>
    <style lang="scss">
    .isBgray{
      background-color: #eeeeee;
      color:gray;
    }
    .isCgray{
      color:gray;
    }
    #RightAlert{
      width:150px;
      height:180px;
      border:1px solid blue;
      background-color:#f9a101;
      position:absolute;
      top:60px;
      left:144px;
      z-index:999999;
      #Triangle{
        width: 0;
        height: 0;
        border-top: 10px solid transparent;
        border-right: 15px solid #f9a101;
        border-bottom: 10px solid transparent;
        position: absolute;
        top: 10px;
        left: -15px;
      }
      #DeleteTop{
      width:30px;
      height:30px;
      border:1px solid blue;
      position: absolute;
      top:0px;
      right:0px;
      background-color:red;
    
      }
    }
    .comp-full-calendar {
      // font-family: "elvetica neue", tahoma, "hiragino sans gb";
      padding: 20px;
      background: #fff;
      max-width: 960px;
      margin: 0 auto;
      ul,
      p {
        margin: 0;
        padding: 0;
      }
    }
    
    .full-calendar-body {
      margin-top: 20px;
      .weeks {
        display: flex;
        border-top: 1px solid #e0e0e0;
        border-bottom: 1px solid #e0e0e0;
        border-left: 1px solid #e0e0e0;
        .week {
          flex: 1;
          text-align: center;
          border-right: 1px solid #e0e0e0;
        }
      }
      .dates {
        position: relative;
        .week-row {
          // width: 100%;
          // position:absolute;
          border-left: 1px solid #e0e0e0;
          display: flex;
          .day-cell {
            flex: 1;
            min-height: 112px;
            padding: 4px;
            border-right: 1px solid #e0e0e0;
            border-bottom: 1px solid #e0e0e0;
            .day-number {
              text-align: center;
              width:25px;
              height:25px;
              line-height:25px;
              float:right;
              border-radius:50%;
            }
              .today {
                 background-color: red;
                 color:#fff;
                 z-index:99999;
                 box-shadow: 2px 2px 2px 2px #888888;
    
            }
            &.not-cur-month {
              .day-number {
                color: rgba(0, 0, 0, 0.24);
              }
            }
          }
        }
        .dates-events {
          position: absolute;
          top: 0;
          left: 0;
          z-index: 1;
          width: 100%;
          .events-week {
            display: flex;
            .events-day {
              cursor: pointer;
              flex: 1;
              padding:4px;
              min-height: 112px;
              overflow: hidden;
              text-overflow: ellipsis;
              position:relative;
              .day-number {
                text-align: center;
                width:25px;
                height:25px;
                line-height:25px;
                float:right;
                border-radius:50%;
              }
                .today {
                 background-color: red;
                 color:#fff;
                 z-index:99999;
              }
              &.not-cur-month {
                .day-number {
                  color: rgba(0, 0, 0, 0.24);
                }
              }
              .event-box {
                // border: 1px solid red;
                padding-top:26px;
                .event-item {
                  cursor: pointer;
                  font-size: 12px;
                  background-color: #c7e6fd;
                  margin-bottom: 2px;
                  color: rgba(0, 0, 0, 0.87);
                  padding: 0 0 0 4px;
                  height: 18px;
                  line-height: 18px;
                  white-space: nowrap;
                  overflow: hidden;
                  text-overflow: ellipsis;
                  &.is-start {
                    margin-left: 4px;
                    // border-top-left-radius:4px;
                    // border-bottom-left-radius:4px;
                  }
                  &.is-end {
                    margin-right: 4px;
                    // border-top-right-radius:4px;
                    // border-bottom-right-radius:4px;
                  }
                  &.is-opacity {
                    opacity: 0;
                  }
                }
                .more-link {
                  cursor: pointer;
                  // text-align: right;
                  padding-left: 8px;
                  padding-right: 2px;
                  color: rgba(0, 0, 0, 0.38);
                  font-size: 14px;
                }
              }
            }
          }
        }
        .more-events {
          position: absolute;
          width: 150px;
          z-index: 2;
          border: 1px solid #eee;
          box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
          .more-header {
            background-color: #eee;
            padding: 5px;
            display: flex;
            align-items: center;
            font-size: 14px;
            .title {
              flex: 1;
            }
            .close {
              margin-right: 2px;
              cursor: pointer;
              font-size: 16px;
            }
          }
          .more-body {
            height: 146px;
            overflow: hidden;
            .body-list {
              height: 144px;
              padding: 5px;
              overflow: auto;
              background-color: #fff;
              .body-item {
                cursor: pointer;
                font-size: 12px;
                background-color: #c7e6fd;
                margin-bottom: 2px;
                color: rgba(0, 0, 0, 0.87);
                padding: 0 0 0 4px;
                height: 18px;
                line-height: 18px;
                white-space: nowrap;
                overflow: hidden;
                text-overflow: ellipsis;
              }
            }
          }
        }
      }
      .FirstGreen{
          background:green;
        }
      .FirstYellow{
          background:yellow;
        }
      .FirstRed{
          background:red;
        }
      .CircleData{
          width:5px;
          height:5px;
          border-radius:100%;
          float:left;
          margin-top:10px;
          margin-left:10px;
        }
    }
    </style>
    

    Step二:引用页面。

    <template>
        <div>
            <!-- 跟随鼠标指针显示内容,勿删 -->
            <!-- <div class="Valuationtable">
                <div class="RightAlert">
                  <div id="Triangle"></div>
                  <div id="DeleteTop" @click.stop="deletetip($event)"><span class="iconfont icon-delete"></span></div>
                  <div class="DetailedAll" >删除估值表</div>
                  <div class="DetailedAll" >删除成交明细</div>
                  <div class="DetailedAll" >删除委托明细</div>
                  <div class="DetailedAll" >删除委托明细</div>
                  <div class="DetailedAll" >删除委托明细</div>
                  <div class="DetailedAll" >删除委托明细</div>
                </div>
        </div> -->
            <!-- Calendar   Container -->
            <div class="CalendarContainer">
                <full-calendar class="test-fc"
                               :events="fcEvents"
                               :firstDay='7'
                               locale="zh-cn"
                               :isshoetitlt="1"
                               lang="zh-cn"
                               ref="CalChildren"
                               @changeMonth="changeMonth"
                               @eventClick="eventClick"
                               @dayClick="dayClick"
                               @DayenterFather="DayenterFather"
                               @DayleaveFather="DayleaveFather"
                               @moreClick="moreClick">
                    <template slot="fc-event-card"
                              slot-scope="p">
                        <p class="EventsTitle"> {{ p.event.title }}</p>
                    </template>
                </full-calendar>
            </div>
        </div>
    </template>
    <script>
    import $ from "jquery";
    // Its dataEvents Template Please do not delete
    let demoEvents = [
      {
        title: "习近平大大",
        start: "2018-07-02",
        end: "2018-07-02"
      }
    ];
    export default {
      components: {
        "full-calendar": require("./fullCalendar").default
      },
      data() {
        return {
          fcEvents: demoEvents,  //显示在日历格中的事件
          starTime: "",
          endTime: "",
          fileList: []
        };
      },
      mounted() {},
      created() {},
      methods: {
        eventClick(event, jsEvent, pos) {
          console.log("eventClick", event, jsEvent, pos);
        },
        dayClick(day, jsEvent, index) {
          //console.log(jsEvent.target);
          // 跟随鼠标指针显示,勿删
          //    var dx = jsEvent.pageX,
          //        dy = jsEvent.pageY;
          // $('.Valuationtable').css({"display":"block","left":(dx+10)+"px","top":(dy-40)+"px"});
          let allevent = document.getElementsByClassName("events-day");
          let alleventBox = document.getElementsByClassName("RightAlert");
          for (var i = 0; i < allevent.length; i++) {
            alleventBox[i].style.display = "none";
          }
          if (jsEvent.target.className == "event-box") {
            $(jsEvent.target.parentNode)
              .find(".RightAlert")
              .show();
          }
          if (jsEvent.target.className == "EventsTitle") {
            $(jsEvent.target.parentNode.parentNode.parentNode)
              .find(".RightAlert")
              .show();
          }
          if (jsEvent.target.className == "day-cell") {
            $(jsEvent.target)
              .find(".RightAlert")
              .show();
          }
          if (jsEvent.target.className == "day-cell isBgray") {
            $(jsEvent.target)
              .find(".RightAlert")
              .show();
          }
          if (jsEvent.target.className == "day-cell not-cur-month") {
            $(jsEvent.target)
              .find(".RightAlert")
              .show();
          }
          if (jsEvent.target.className == "day-cell not-cur-month isBgray") {
            $(jsEvent.target)
              .find(".RightAlert")
              .show();
          }
          if (jsEvent.target.className == "day-number isCgray") {
            $(jsEvent.target.parentNode)
              .find(".RightAlert")
              .show();
          }
          if (jsEvent.target.className == "day-number") {
            $(jsEvent.target.parentNode)
              .find(".RightAlert")
              .show();
          }
          if (jsEvent.target.className == "day-number today") {
            $(jsEvent.target.parentNode)
              .find(".RightAlert")
              .show();
          }
    
          if (jsEvent.target.className == "day-number not-cur-month isCgray") {
            $(jsEvent.target.parentNode)
              .find(".RightAlert")
              .show();
          }
          if (jsEvent.target.className == "day-number not-cur-month") {
            $(jsEvent.target.parentNode)
              .find(".RightAlert")
              .show();
          }
        },
        DayenterFather(day, jsEvent) {
          jsEvent.target.style.boxShadow = " 0px 6px 18px rgba(0, 0, 0, 0.22)";
        },
        DayleaveFather(day, jsEvent) {
          jsEvent.target.style.boxShadow = "0px 0px 0px 0px #fff";
        },
        moreClick(day, events, jsEvent) {
          console.log("moreCLick", day, events, jsEvent);
        },
        changeMonth(start, end, current) {
          let starttime = start.format().slice(0, 10);
          let endtime = end.format().slice(0, 10);
          this.starTime = starttime;
          this.endTime = endtime;
        }
      }
    };
    </script>
    <style lang='scss'>
    .otcDialog {
      .el-input__inner {
        padding-right: 25px;
      }
      .el-dialog {
        //height:400px;
      }
      td {
        padding: 0 14px;
        width: 50%;
      }
      .form-parent > form {
        background-color: #fff;
        -webkit-box-shadow: none;
        -moz-box-shadow: none;
        box-shadow: none;
        padding-bottom: 20px;
        //input {text-align: right;}
      }
      .grid-label {
        white-space: nowrap;
        max-width: 250px;
        word-break: normal;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        float: left;
        line-height: 20px;
      }
    }
    .CalendarContainer {
      background: #ffffff;
      margin: 0px 20px 0px 20px;
      box-shadow: 0 3px 7px #ddd;
    }
    .CalendarSubject {
      margin: 0 20px;
    }
    .dataTile {
      font-size: 20px;
      /*height: 30px;*/
      line-height: 30px;
      font-weight: bold;
      color: #000;
      padding-right: 30px;
      .titleTextBefore:before {
        position: relative;
        top: 3.5px;
        content: "";
        display: inline-block;
        width: 5px;
        height: 20px;
        background: #f9a101;
        margin: 0 12px 0 0;
      }
    }
    .FL {
      float: left;
    }
    .titleVertical {
      width: 5px;
      height: 20px;
      background: #f9a101;
      margin: 5px 12px 0px 10px;
    }
    // 跟随鼠标指针显示的样式勿删
    .Valuationtable {
      display: none;
      position: absolute;
      z-index: 99999;
      background: #000;
      .RightAlert {
        // width: 130px;
        // height: 165px;
        background-color: #f9a101;
        padding: 5px 20px 5px 20px;
        border-radius: 5px;
        z-index: 999999;
      }
      #Triangle {
        width: 0;
        height: 0;
        border-top: 10px solid transparent;
        border-right: 15px solid #f9a101;
        border-bottom: 10px solid transparent;
        position: absolute;
        top: 10px;
        left: -15px;
      }
    
      .DetailedAll {
        width: 100%;
        height: 20px;
        line-height: 20px;
        margin-top: 6px;
        text-align: center;
        color: #fff;
      }
    
      #DeleteTop {
        width: 25px;
        height: 25px;
        position: absolute;
        top: 3px;
        right: 3px;
        text-align: center;
        line-height: 25px;
        color: #000;
        background: #f3f3f3;
      }
    }
    </style>
    

    注释:

    vue-fullcalendar

    现在适用于Vue2。这是一个基于vue.js的fullCalendar组件。目前,它只支持月视图。它受到fullCalendar.io的启发,但没有被它克隆。因此,请阅读下面的文档以了解所有功能。

    Demo

    demo.gif

    Example

    export default {
      components: {
        "full-calendar": require("./fullCalendar").default
      },
    }
    <full-calendar :events="fcEvents" locale="en"></full-calendar>
    
    var demoEvents = [
        {
          title : 'Sunny Out of Office',
          start : '2016-08-25',
          end : '2017-07-27'
        }
    ]
    export default {
      data () {
        return {
          fcEvents : demoEvents
        }
      },
      components : {
        'full-calendar': require('vue-fullcalendar')    
      }
    }
    
    Yeah you see the calendar

    对应的属性和事件

    props

    1. events :事件将显示在日历上

      events = [
        {
          title     :  'event1',
          start     : '2016-07-01',
          cssClass  : 'family',
          YOUR_DATA : {}
        },
        {
          title     : 'event2',
          start     : '2016-07-02',
          end       : '2016-07-03',
          cssClass  : ['family', 'career']
          YOUR_DATA : {}
        }
      ]         
      
      • title 是此活动的标题,将显示在日历上

      • start 是这个活动的开始日

      • end 是这个活动的结束日

      • cssClass 是每个事件标签的css类,这样,你就可以设置不同的颜色,样式..

      • YOUR_DATA 您可以定义尽可能多的数据

    2. locale :像monthNames weekNames和titleFormat这样的东西。支持与moment.js相同的语言环境

    3. firstDay : 一周的第一天Number,默认:0(星期日)星期日= 0,星期一= 1,星期二= 2等。任何小于0或大于6的数字都将设置为0。

      • default : 0

    events

    fc will dispatch some events out.

    1. changeMonth :每次你点击下一个/上个月的箭头,fc都会调度changeMonth

      this.$dispatch('changeMonth', start, end, current)
      
      • start 是当前月份的第一天查看(moment对象)

      • end 是当前月份的最后一天查看(moment对象)

      • current 是本月的第一天(moment对象)

    2. eventClick : 每次单击事件时,fc都会调度eventClick

      this.$dispatch('eventClick', event, jsEvent, pos)
      
      • event 是一个Event对象,用于保存事件的信息

      • jsEvent持有本机javascript事件

      • pos是fc的相对坐标

    1. dayClick : fc在您点击日期广告位时发送它。

      this.$dispatch('eventClick', day, jsEvent)
      
      • date是您单击(moment对象)的日期对象

      • jsEvent 持有本机javascript事件

    2. moreClick :fc在点击more按钮时发送它

      • date 是与“更多”单击(moment对象)对应的日期

      • events是框中的事件列表

      • jsEvent持有本机javascript事件

    slots

    You will be able to register your own stuff by using slots

    1. fc-header-left : top left area

    2. fc-header-right : top right area. In my case, I added a filter menu there

    3. fc-body-card : inside the body area, usually working with EventClick, to display a event detail

    END

    最后需要改写一个大神,封装好了的,我只是拿来用加以修改,详情请看下文。
    vue-fullCalendar.vue

    相关文章

      网友评论

          本文标题:vue-elementUi-Calendar前端日历插件折腾记

          本文链接:https://www.haomeiwen.com/subject/sojcxqtx.html