带备注的日历组件(3.0)

上一版的日历组件是改的element-ui的,使用不方便,今天我也是闲了一会儿,就自己写了原生的,不依赖其他框架;其他个人定义组件
先看效果图:很简洁,后期可以加
在这里插入图片描述
组件API
width:组件宽度
makeArr:备注列表(传入一个数组:[{time:‘2020-02-28’,remark:‘28号测试备注’}])
dayChange:当前激活日期change事件
monthChange:月份变化change事件

calendar.vue

<template>
<!-- 
  dayChange:当前激活日期change事件
  monthChange:月份变化change事件
 -->
  <div class="lq-calendar" :style="'width:'+width">
    <div class="calendar-header">
      <div class="header-left">{{active.showText}}</div>
      <div class="header-right">
        <span class="btn" @click="setActiveMonth(1)">上个月</span>
        <span class="btn" @click="setActiveMonth(2)">今天</span>
        <span class="btn" @click="setActiveMonth(3)">下个月</span>
      </div>
    </div>
    <div class="calendar-content">
      <div class="calendar-week">
        <span class="calendar-week-span" v-for="(item,index) in week" :key="index">{{item}}</span>
      </div>
      <div class="calendar-month">
        <span
          class="calendar-month-span"
          @click="setDay(item)"
          :class="checkState(item)"
          v-for="(item,index) in month"
          :key="index"
          :ref="'day'+index"
        >{{item.day}}</span>
      </div>
      <div class="calendar-remark">{{active.remark}}</div>
    </div>
  </div>
</template>

<script>
Date.prototype.format = function(fmt) {
  var o = {
    'M+': this.getMonth() + 1, //月份
    'd+': this.getDate(), //日
    'h+': this.getHours(), //小时
    'm+': this.getMinutes(), //分
    's+': this.getSeconds(), //秒
    'q+': Math.floor((this.getMonth() + 3) / 3), //季度
    S: this.getMilliseconds() //毫秒
  }
  if (/(y+)/.test(fmt))
    fmt = fmt.replace(
      RegExp.$1,
      (this.getFullYear() + '').substr(4 - RegExp.$1.length)
    )
  for (var k in o)
    if (new RegExp('(' + k + ')').test(fmt))
      fmt = fmt.replace(
        RegExp.$1,
        RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length)
      )
  return fmt
}
export default {
  props: {
    width: {
      type: [String, Number],
      default: '500px'
    },
    makeArr: {
      type: Array,
      default: () => {
        return []
      }
    }
  },
  data() {
    return {
      today: '',
      week: ['一', '二', '三', '四', '五', '六', '日'],
      month: [],
      activeMonth: {}, //当前选中的
      active: {
        remark: '',
        showText: '' //当前月份
      }
    }
  },
  methods: {
    //day单击事件
    setDay(obj) {
      if (obj.month == this.activeMonth.month) {
        this.activeMonth = {}
        this.active.remark = ''
        this.checkState({})
      } else {
        this.active.remark = obj.remark
        this.activeMonth = obj
        this.checkState(obj)
      }
      this.$emit('dayChange',obj)
    },
    //备注匹配
    checkMakeArr() {
      let num = this.makeArr.length
      for (let i = 0; i < num; i++) {
        for (let j = 0; j < 42; j++) {
          if (this.makeArr[i].time == this.month[j].month) {
            this.month[j].remark = this.makeArr[i].remark
            continue
          }
        }
      }
    },
    //日历表格状态判定
    checkState(val) {
      let sty = []
      if (!val.state) {
        sty.push('calendar-month-state') //不属于本月css
      }
      if (val.month == this.today) {
        sty.push('calendar-month-today') //今日css
      }
      if (val.remark != undefined) {
        sty.push('calendar-month-remark') //有备注css
      }
      if (val.month == this.activeMonth.month) {
        sty.push('calendar-month-click') //当前单击激活的css
      }
      return sty.join(' ')
    },
    //月份选择
    setActiveMonth(val) {
      let timeVal = this.active.showText
      let prevmonth = new Date(new Date(timeVal).setDate(0)).format(
        'yyyy-MM-dd'
      )
      let nextmonth = new Date(new Date(timeVal).setDate(32)).format(
        'yyyy-MM-dd'
      )
      //val:1上个月,2今天,3下个月
      switch (val) {
        case 1:
          this.getMonth(prevmonth)
          break
        case 2:
          this.getMonth(this.today)
          break
        case 3:
          this.getMonth(nextmonth)
          break
      }
      this.$emit('monthChange',this.active.showText)
    },
    //星期判断
    checkWeek(val) {
      var date = new Date(val)
      var day = date.getDay()
      var wstr = '日一二三四五六'.charAt(day)
      return { weekday: day, weekstr: wstr }
    },
    //今日日期
    getTime() {
      var today = new Date()
      this.today = today.format('yyyy-MM-dd')
    },
    //日历矩阵处理
    getMonth(val) {
      this.month = []
      var thismonth1 = new Date(new Date(val).setDate(1)).format('yyyy-MM')
      this.active.showText = thismonth1
      var thismonth2 = new Date(
        new Date(new Date().setMonth(new Date(val).getMonth() + 1)).setDate(0)
      ).format('yyyy-MM-dd')
      let num = parseInt(thismonth2.substr(8, 2))
      for (let i = 1; i <= num; i++) {
        let obj = {
          month: '',
          showText: thismonth1,
          day: '',
          state: true
        }
        if (i < 10) {
          obj.month = thismonth1 + '-0' + i
          obj.day = '0' + i
        } else {
          obj.month = thismonth1 + '-' + i
          obj.day = i
        }
        obj = { ...obj, ...this.checkWeek(obj.month) }
        this.month.push(obj)
      }
      this.setMonthBefore()
      this.setMonthAfter()
      this.checkMakeArr()
    },
    //日历矩阵处理 之前日期
    setMonthBefore() {
      let timeVal = this.month[0]
      let num = timeVal.weekday == 0 ? 7 : timeVal.weekday
      for (let i = 1; i < num; i++) {
        let obj = {
          month: '',
          day: '',
          state: false
        }
        obj.month = new Date(
          new Date(timeVal.month).setDate(new Date(timeVal.month).getDate() - i)
        ).format('yyyy-MM-dd')
        obj.showText = obj.month.substr(0, 7)
        obj.day = obj.month.substr(8, 2)
        obj = { ...obj, ...this.checkWeek(obj.month) }
        this.month.unshift(obj)
      }
    },
    //日历矩阵处理 之后日期
    setMonthAfter() {
      let timeVal = this.month[this.month.length - 1]
      let num = 42 - this.month.length
      for (let i = 1; i <= num; i++) {
        let obj = {
          month: '',
          day: '',
          state: false
        }
        obj.month = new Date(
          new Date(
            new Date().setMonth(new Date(timeVal.month).getMonth() + 1)
          ).setDate(i)
        ).format('yyyy-MM-dd')
        obj.showText = obj.month.substr(0, 7)
        obj.day = obj.month.substr(8, 2)
        obj = { ...obj, ...this.checkWeek(obj.month) }
        this.month.push(obj)
      }
    }
  },
  created() {
    this.getTime()
    this.getMonth(this.today)
  }
}
</script>

<style lang='less' scoped>
.lq-calendar {
  padding: 20px;
  .calendar-header {
    display: flex;
    align-items: center;
    padding: 0 calc(7.14% - 20px);
    justify-content: space-between;
    .btn {
      cursor: pointer;
      display: inline-block;
      padding: 5px 10px;
      text-align: center;
      border: 1px solid #eae7e7;
      outline: none;
    }
    .btn:hover {
      background-color: #00cc8b;
      color: #fff;
    }
  }
  .calendar-content {
    padding-top: 20px;
    .calendar-week {
      display: flex;
      justify-content: center;
    }
    .calendar-week-span {
      color: #666;
      width: 20%;
      display: inline-block;
      text-align: center;
    }
    .calendar-month {
      padding-top: 20px;
      display: flex;
      justify-content: flex-start;
      flex-wrap: wrap;
    }
    .calendar-month-span {
      position: relative;
      color: #333;
      cursor: pointer;
      width: 14.28%;
      display: inline-block;
      text-align: center;
      height: 0;
      padding-bottom: 7.14%;
      line-height: 14.28%;
      padding-top: 7.14%;
      outline: #00cc8b;
    }
    .calendar-month-span:hover {
      background-color: rgba(0, 204, 139, 0.5);
      color: #fff;
    }
    .calendar-month-state {
      color: #999;
    }
    .calendar-month-click {
      background-color: rgba(0, 204, 139, 0.5);
      color: #fff;
    }
    .calendar-month-today {
      color: #fff;
      background-color: #00cc8b;
    }
    .calendar-month-remark::after {
      position: absolute;
      content: '';
      bottom: 3px;
      left: 50%;
      width: 6px;
      height: 6px;
      margin-left: -3px;
      border-radius: 50%;
      background-color: #00cc8b;
    }
  }
  .calendar-remark {
    padding: 0 5.14%;
  }
}
</style>
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值