zoukankan      html  css  js  c++  java
  • vue 实现日历组件

    组件代码

    <template>
      <div class="air-calendar-box">
        <table class="sn-calendar-table">
          <thead>
            <th class="fc-day-header">日</th>
            <th class="fc-day-header">一</th>
            <th class="fc-day-header">二</th>
            <th class="fc-day-header">三</th>
            <th class="fc-day-header">四</th>
            <th class="fc-day-header">五</th>
            <th class="fc-day-header">六</th>
          </thead>
          <tbody>
            <tr>
              <td 
                v-for="(item, idx) in calendarData"
                :key="idx"
                :style="{'height': height}"
                :class="{
                  'include': item.include,
                  'active': activeData && item.date === activeData.date
                }"
                @click="clickDay(item)">
                <slot name="day" :row="item">
                  <div class="day">
                    {{ item.day2 }}
                  </div>
                </slot>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </template>
    <script>
    export default {
      name: 'AirCalendarBox',
      props: {
        type: {
          // all 可选中显示的所有日期 portion 只能选中当前月份的数据
          type: String,
          default: 'portion'
        },
        // 默认值
        defaultMonth: {
          type: Date,
          default () {
            let year = new Date().getFullYear() // 当月年份
            let month = new Date().getMonth() + 1 // 当月月份
            return new Date(year, month - 1, 1)
          }
        },
        height: {
          type: String,
          default: '52px'
        }
      },
      watch: {
        defaultMonth () {
          this.setDefaultValue()
          this.getCalendarDay()
        }
      },
      data () {
        return {
          calendarData: [],
          activeData: null
        }
      },
      created () {
        this.getCalendarDay()
      },
      methods: {
        // 获取日历天数
        getCalendarDay () {
          let year = new Date(this.defaultMonth).getFullYear() // 当月年份
          let month = new Date(this.defaultMonth).getMonth() + 1 // 当月月份
          let days = new Date(year, month, 0).getDate() // 当月天数

          let prevYear = month === 1 ? (year - 1) : year // 上一年年份
          let prevMonth = month === 1 ? 12 : (month - 1) // 上月月份
          let prevDays = new Date(prevYear, prevMonth, 0).getDate() // 上一月天数

          let lastYear = month === 12 ? (year + 1) : year // 下一年年份
          let lastMonth = month === 12 ? 1 : (month + 1) // 下月月份
          // let lastDays = new Date(lastYear, lastMonth, 0).getDate() // 下一月天数

          let prevMonthArr = [] // 上月数据
          let nextMonthArr = [] // 下月数据
          let currentMonthArr = [] // 当月数据
          // 判断当月1号是星期几
          let firstDay = new Date(year, month - 1, 1).getDay()
          // 获取显示上月的数据
          for (let i = 0; i < firstDay; i++) {
            let day = prevDays - firstDay + (i + 1)
            let day2 = day >= 10 ? day : ('0' + day)
            let month2 = prevMonth >= 10 ? prevMonth : ('0' + prevMonth)
            prevMonthArr.push({
              year: prevYear,
              month: prevMonth,
              month2: month2,
              day: day,
              day2: day2,
              date: `${prevYear}-${prevMonth}-${day}`,
              date2: `${prevYear}-${month2}-${day2}`,
              include: false
            })
          }
          // 获取显示的下一月的数据
          for (let i = 0; i < (42 - firstDay - days); i++) {
            let day = i + 1
            let day2 = day >= 10 ? day : ('0' + day)
            let month2 = lastMonth >= 10 ? lastMonth : ('0' + lastMonth)
            nextMonthArr.push({
              year: lastYear,
              month: lastMonth,
              month2: month2,
              day: day,
              day2: day2,
              date: `${lastYear}-${lastMonth}-${day}`,
              date2: `${lastYear}-${month2}-${day2}`,
              include: false
            })
          }
          // 获取当月显示数据
          for (let i = 1; i <= days; i++) {
            let day2 = i >= 10 ? i : ('0' + i)
            let month2 = month >= 10 ? month : ('0' + month)
            currentMonthArr.push({
              year: year,
              month: month,
              month2: month2,
              day: i,
              day2: day2,
              date: `${year}-${month}-${i}`,
              date2: `${year}-${month2}-${day2}`,
              include: true
            })
          }
          this.calendarData = [...prevMonthArr, ...currentMonthArr, ...nextMonthArr]
        },
        // 设置默认值
        setDefaultValue (date) {
          if (!date) {
            this.activeData = null
            return
          }
          let year = new Date(date).getFullYear() // 当月年份
          let month = new Date(date).getMonth() + 1 // 当月月份
          let month2 = month >= 10 ? month : ('0' + month)
          let day = new Date(date).getDate()
          let day2 = day >= 10 ? day : '0' + day
          let row = {
            year: year,
            month: month,
            month2: month2,
            day: day,
            day2: day2,
            date: `${year}-${month}-${day}`,
            date2: `${year}-${month2}-${day2}`,
            include: true
          }
          this.clickDay(row)
        },
        clickDay (row) {
          if (this.type === 'portion' && !row.include) {
            this.$message({
              type: 'info',
              message: '只能选择当前月份的日期'
            })
            return
          }
          this.activeData = { ...row }
          this.$emit('click', { ...row })
        }
      }
    }
    </script>
    <style lang="less" scoped>
    .air-calendar-box {
      .sn-calendar-table {
         100%;
        border-radius: 4px;
        display: block;
        overflow: hidden;
        thead,
        tbody {
          display: flex;
           100%;
        }
        tr {
           100%;
        }
        th {
          background:#D9F5F5;
          height: 32px;
          line-height: 32px;
          text-align: center;
          color: #3E597B;
          box-sizing: border-box;
          display: inline-block;
           14.28%;
        }
        td {
           14.28%;
          display: inline-block;
          position: relative;
          font-size: 16px;
          font-weight: 500;
          box-sizing: border-box;
          text-align: center;
          cursor: pointer;
          border: solid 2px transparent;
          color: rgba(62, 89, 123, 0.3);
          &.include {
            color: #3E597B;
          }
          &.active {
            border: 2px solid #00BBBB;
          }
          .day {
            height: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
          }
          &:nth-child(1),
          &:nth-child(7),
          &:nth-child(8),
          &:nth-child(14),
          &:nth-child(15),
          &:nth-child(21),
          &:nth-child(22),
          &:nth-child(28),
          &:nth-child(29),
          &:nth-child(35),
          &:nth-child(36),
          &:nth-child(42) {
            background: #EBFAFA;
          }
        }
        tbody {
          .clickDay {
            border: solid 2px #00BBBB;
          }
        }
      }
    }

    </style>

    // 页面效果

  • 相关阅读:
    Python——方法
    Python——类和对象(二)
    Python——类和对象(一)
    Python——函数的高级应用
    Python——函数入门(三)
    Python——函数入门(二)
    Python——函数入门(一)
    Python——序列封包与序列解包
    min(T)方法
    max(T)方法
  • 原文地址:https://www.cnblogs.com/fczbk/p/14985259.html
Copyright © 2011-2022 走看看