基于VUE的考勤日历(带图标)

1、在src文件夹下创建文件名为scheduleCalendar的文件夹,与page并列。

2、scheduleCalendar文件里

(1)、calendar.vue




(2)、dateCell.vue



      

(3)、eventItem.vue



(4)、header.vue




(5)、index.js

import calendar from './calendar'

export default calendar

if (window.Vue) {
    Vue.component(calendar.name, calendar)
}

(6)、month.vue




(7)、picker.vue




(8)、util.js

import Vue from 'vue'

/**
 * 事件总线
 */
 export const EventBus = new Vue()

/**
 * 是否闰年
 * @param {*} year
 */
 const isLeap = year => (year % 100 !== 0 && year % 4 === 0) || year % 400 === 0

/**
 * 计算某月天数
 * @param {*} param0 { year, month }
 */
 export const calcDays = ({ year, month }) => {
  let num = 31

  switch (month + 1) {
    case 2:
    num = isLeap(year) ? 29 : 28
    break
    case 4:
    case 6:
    case 9:
    case 11:
    num = 30
    break
  }
  return num
}

const siblingsMonth = (y, m, n) => {
  const date = new Date(y, m, 1)
  date.setMonth(m + n)
  return {
    year: date.getFullYear(),
    month: date.getMonth()
  }
}

/**
 * 上一月的年份和月份
 * @param {*} year
 * @param {*} month
 */
 export const calcPrevMonth = (year, month) => siblingsMonth(year, month, -1)

/**
 * 下一月的年份和月份
 * @param {*} year
 * @param {*} month
 */
 export const calcNextMonth = (year, month) => siblingsMonth(year, month, 1)

/**
 * 某月第一天是星期几
 * @param {*} year
 * @param {*} month
 */
 const firstWeek = (year, month) => new Date(year, month, 1).getDay()

 export const PREV_DATE_TYPE = 'prev'
 export const CURRENT_DATE_TYPE = 'current'
 export const NEXT_DATE_TYPE = 'next'

/**
 * 月历
 * @param {*} year
 * @param {*} month
 * @param {*} startWeek
 */
 export const monthlyCalendar = (year, month, startWeek) => {
  const result = []
  const curMonth = {
    year,
    month
  }
  const days = calcDays(curMonth)
  const prevMonth = calcPrevMonth(year, month)
  const prevDays = calcDays(prevMonth)
  const prevOver = (firstWeek(year, month) || 7) - startWeek
  const nextMonth = calcNextMonth(year, month)

  for (let p = prevDays - prevOver + 1; p <= prevDays; p++) {
    result.push({
      date: new Date(prevMonth.year, prevMonth.month, p),
      type: PREV_DATE_TYPE
    })
  }

  for (let c = 1; c <= days; c++) {
    result.push({
      date: new Date(curMonth.year, curMonth.month, c),
      type: CURRENT_DATE_TYPE
    })
  }

  for (let n = 1, nl = 42 - result.length; n <= nl; n++) {
    result.push({
      date: new Date(nextMonth.year, nextMonth.month, n),
      type: NEXT_DATE_TYPE
    })
  }

  return result
}

const tryParse = obj => (typeof obj === 'string' ? new Date(obj) : obj)

/**
 * 是否是同一天
 * @param {*} one
 * @param {*} two
 */
 export const isSameDay = (one, two) => {
  const oneDate = tryParse(one)
  const twoDate = tryParse(two)
  return (
    oneDate.getDate() === twoDate.getDate() &&
    oneDate.getMonth() === twoDate.getMonth() &&
    oneDate.getFullYear() === twoDate.getFullYear()
    )
}

const fillZero = value => (value < 10 ? `0${value}` : value)
export const format = (date, exp = 'yyyy年MM月dd日') => {
  const y = date.getFullYear()
  const m = date.getMonth() + 1
  const d = date.getDate()

  return exp
  .replace('yyyy', y)
  .replace('MM', fillZero(m))
  .replace('dd', fillZero(d))
}

// 记录一些公共数据
export const Store = {
    hasExpand: false // 当前是否有展开的单元格
  }

(9)、variables.less

// colors
@sc-base-color: #444;
@sc-gray-color: #666;
@sc-gray-light-color: #999;
@sc-primary-color: #2196f3;
@sc-primary-light-color: #bbdefb;
@sc-primary-dark-color: #1976d2;
@sc-body-color: #fff;
@sc-border-color: #e8e8e8;
@sc-gray-background: #f2f2f2;

// fontSize
@sc-base-font-size: 14px;

// box-shadow
@sc-box-shadow: 0 3px 15px rgba(0, 0, 0, .2), 0 -2px 6px rgba(0, 0, 0, .2);

// header
@sc-header-height: 60px;
@sc-header-padding: 10px;
@sc-header-fs: 18px;

// week
@sc-week-height: 40px;

// date
@sc-data-label-size: 30px;

// details
@sc-details-width: 125%;
@sc-details-height: 300px;
@sc-details-hd-height: 30px;

// picker
@sc-picker-height: 210px;

@sc-cell-min-width: 94px;

(10)、week.vue




3、引用

在data定义字段中:

events: [],
itemRender(item) {
  const h = this.$createElement
  return h('i', '')
},
pickerOptions: {
  disabledDate: (time) => {
    return this.dealDisabledDate(time);
  }
}

create中:

created() {
  // 显示为当月的数据
  const now = new Date()
  this.events = this.events.map(item => {
    const d = item.date.split('-')[2]
    item.date = `${now.getFullYear()}-${now.getMonth() + 1}-${d}`
    return item
  })
}

methods中:

      changeDate(e, item, date) {
        const updateIndex = this.events.findIndex(ele => ele.id === item.id)
        this.$set(this.events, updateIndex, {
          ...this.events[updateIndex],
          date
        })
      },
      dateSelect(year, month) {
        let _month = ''
        if ((month + 1)<10) {
          _month = '0' + (month + 1)
        } else {
          _month = month + 1
        }
        let _date = year + '-' + _month
        this.kaoqinInfo(_date)
      }     

注意:从后台接口获取到的数据格式如下kaoQinList.push({id:'k'+i, date:e.Date, text:e.DataInfor, status: 1}),其中status是考勤日历的状态,从而决定显示什么样的图标,比如有请假、出差等考勤状态,以图标的形式显示在日历对应的日期里。

你可能感兴趣的:(基于VUE的考勤日历(带图标))