0
点赞
收藏
分享

微信扫一扫

vue el-Calendar日历使用

刘员外__ 2022-04-18 阅读 66

效果图

 

 

子组件:

<template>
  <div class="dateInfo">
    <div class="item">
      <span class="day" :show="itemdate.oneDay.length > 0 ? 'show' : false">
        {{ itemdate.data.split('-').slice(2).join('-') }}
      </span>
      <template>
        <div v-for="(item, index) in itemdate.oneDay" :key="index" class="today">
          <el-popover placement="right" width="width" popper-class="contestPopper" trigger="hover">
            <div class="top">
              <h2>
                {{ item.title }} <img v-if="item.isGoodsRewards == '1'" src="@/assets/contest/gift.png" alt="" /><img
                  v-if="item.isMoneyRewards == '1'"
                  style="height: 26px"
                  src="@/assets/contest/money.png"
                  alt=""
                />
              </h2>
              <div class="time">
                <img src="@/assets/contest/time.png" alt="" />竞赛时间:
                {{ parseTime(item.startTime, '{y}年{m}月{d}日 {h}:{i}') + ' ~ ' + parseTime(item.endTime, '{y}年{m}月{d}日 {h}:{i}') }}
              </div>
            </div>
            <div class="footer">
              <span
                class="sign-up-ing"
                :class="
                  item.status == 1
                    ? 'sign-up-ing1'
                    : item.status == 2
                    ? 'sign-up-ing2'
                    : item.status == 3 || item.status == 4
                    ? 'sign-up-ing4'
                    : item.status == 5
                    ? 'sign-up-ing5'
                    : ''
                "
                >{{
                  item.status == 1
                    ? '预热中'
                    : item.status == 2
                    ? '报名中'
                    : item.status == 3 || item.status == 4
                    ? '比赛中'
                    : item.status == 5
                    ? '已结束'
                    : ''
                }}</span
              >
              <span class="time" v-if="new Date().getTime() < item.startTime">距开始:{{ timeOften(new Date().getTime(), item.startTime) }}</span>
              <nuxt-link :to="`/contest/contestdetail/${item.id}`" class="join" :class="getClass(item.status)">{{
                item.status < 5 ? '进入比赛' : '虚拟竞赛'
              }}</nuxt-link>
            </div>
            <span class="itemdate" slot="reference" :class="item.status == 5 ? 'xuni' : item.status == 4 ? 'jinxingzhong' : ''"
              ><i></i>{{ parseTime(item.startTime, '{h}:{i}') }} {{ item.title }}
            </span>
          </el-popover>
        </div>
      </template>
    </div>
  </div>
</template>

<script>
import { parseTime, timeOften } from '@/utils'
import { Popover } from 'element-ui'
export default {
  name: 'ItemCalendar',
  props: ['itemdate'],
  data() {
    return {
      parseTime
    }
  },
  created() {},
  mounted() {},
  methods: {
    getClass(status) {
      if (status == 5) {
        return 'is-over'
      }
      if (status == 0 || status == 1 || status == 2) {
        return 'is-sign'
      }
      if (status == 3 || status == 4) {
        return 'is-active'
      }
    },
    timeOften(startTime, endTime) {
      return timeOften(startTime, endTime)
    }
  },
  watch: {},
  computed: {},
  components: {
    [Popover.name]: Popover
  }
}
</script>
<style lang="scss" scoped>
.dateInfo {
  display: flex;
  flex-direction: column;
}
.item {
  display: flex;
  flex-direction: column;
  padding-top: 7px;
  .day {
    text-align: center;
    font-size: 18px;
    font-family: PingFangSC-Medium, PingFang SC;
    font-weight: 500;
    color: #9a9a9a;
    margin-bottom: 10px;
  }
}
.today:last-child {
  .itemdate {
    margin-bottom: 0;
  }
}
.itemdate {
  background: #e3f7f8;
  padding: 5px 8px;
  display: flex;
  font-size: 14px;
  font-family: PingFangSC-Regular, PingFang SC;
  font-weight: 400;
  color: #5d5d5d;
  position: relative;
  margin-bottom: 5px;

  i {
    position: absolute;
    left: 0;
    top: 0;
    width: 3px;
    height: 100%;
    background: #11999e;
  }
}
.xuni {
  background: #e9f4ff;
  i {
    background: #309afc;
  }
}
.jinxingzhong {
  background: #fff5eb;
  i {
    background: #ff8f2e;
  }
}
</style>

父组件代码:

template: 

<template>
  <div class="Calendar-index">
    <Header name="竞赛" />
    <main class="contest-container">
      <div class="title">
        <nuxt-link to="/contest" class="back"><img src="~@/assets/contest/contest-back-index.png" alt="" /> 返回竞赛首页</nuxt-link>
      </div>
      <client-only>
        <div class="container">
          <el-calendar :first-day-of-week="7" v-model="value" ref="calendar">
            <!-- 这里使用的是 2.5 slot 语法,对于新项目请使用 2.6 slot 语法-->
            <template slot="dateCell" slot-scope="{ date, data }">
              <!-- <p :class="data.isSelected ? 'is-selected' : ''">{{ formData(data.day) }}</p> -->
              <ItemCalendar :itemdate="formData(data.day)" />
            </template>
          </el-calendar>
        </div>
      </client-only>
    </main>
  </div>
</template>
export default {
  name: 'ContestCalendar',
  data() {
    return {
      monthInfo: [],
      value: new Date()
    }
  },
  created() {},
  mounted() {
    this.queryMonthMatch(parseTime(new Date(), '{y}{m}'))  
    this.$nextTick(() => {
      // 点击前一个月
      let prevBtn = document.querySelector('.el-calendar__button-group .el-button-group>button:nth-child(1)')
      if (prevBtn) {
        prevBtn.addEventListener('click', () => {
          this.queryMonthMatch(parseTime(this.value, '{y}{m}'))
        })
      }
    })

    this.$nextTick(() => {
      // 点击后一个月
      let prevBtn = document.querySelector('.el-calendar__button-group .el-button-group>button:last-child')
      if (prevBtn) {
        prevBtn.addEventListener('click', () => {
          this.queryMonthMatch(parseTime(this.value, '{y}{m}'))
        })
      }
    })
  },
  beforeDestroy() {//销毁绑定事件
    let prevBtnPre = document.querySelector('.el-calendar__button-group .el-button-group>button:nth-child(1)')
    let prevBtnNext = document.querySelector('.el-calendar__button-group .el-button-group>button:last-child')
    prevBtnPre.removeEventListener('click', () => {
      this.queryMonthMatch(parseTime(this.value, '{y}{m}'))
    })
    prevBtnNext.removeEventListener('click', () => {
      this.queryMonthMatch(parseTime(this.value, '{y}{m}'))
    })
  },
  methods: {
//prop传承搞定子组件需要的数据
    formData(data) {
      let len = this.monthInfo.length

      let res = { data, oneDay: [] }

      if (len > 0) {
        for (let i = 0; i < len; i++) {
          let oneDay = parseTime(this.monthInfo[i].startTime, '{y}-{m}-{d}')
          if (data == oneDay) {
            res.oneDay.push(this.monthInfo[i])
            // break
          }
        }
      }
      return res
    },
    async queryMonthMatch(yymm) {
      const r = await queryMonthMatch({ yymm })
      if (r.error_no == '0') {
        this.monthInfo = r.data
      } else {
        this.monthInfo = []
      }
    }
  },
  watch: {},
  computed: {},
   
}

css:

.Calendar-index {
  background-color: #f2f2f2;
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  .contest-container {
    width: 1200px;
    margin: 15px auto;
    flex: 1;
    padding: 0 30px 30px;
    background: #fff;
    border-radius: 8px;
    .title {
      height: 60px;
      line-height: 60px;
      .back {
        cursor: pointer;
        line-height: 60px;
        font-size: 16px;
        font-family: PingFangSC-Regular, PingFang SC;
        font-weight: 400;
        color: #7c7c7c;

        img {
          width: 7px;
          height: 10px;
          margin-right: 8px;
        }
      }
    }
    .container {
      ::v-deep .el-calendar {
        .el-calendar__header {
          background: #e8f5f5;
          height: 64px;
          line-height: 64px;
          padding: 15px 0;
          .el-calendar__title {
            position: absolute;
            left: 50%;
            transform: translate(-50%);
            font-size: 20px;
            font-family: PingFangSC-Medium, PingFang SC;
            font-weight: 500;
            color: #2b2b2b;
          }
        }
        .el-calendar-table__row {
          .prev,
          .next {
            .day {
              display: none;
            }
            .day[show] {
              display: block;
            }
          }
        }
        .el-calendar-table {
          width: 100%;
          height: 100%;
          &:not(.is-range) {
            //使不是本月的日期不可点击,不会跳转到其他月份
            td.next {
              pointer-events: none;
            }
            td.prev {
              pointer-events: none;
            }
          }
        }

        .el-calendar-table td.is-selected {
          background-color: transparent;
        }
        .el-calendar__button-group {
          width: 100%;
          padding: 10px 15px;

          .el-button-group {
            display: flex;
            align-content: center;
            justify-content: space-between;
          }
          .el-button-group::after,
          .el-button-group::before {
            content: unset;
          }
          .el-button {
            padding: 0;
          }
          .el-button-group > .el-button:not(:first-child):not(:last-child) {
            display: none;
          }

          .el-button-group > .el-button:first-child {
            border: none;
            align-self: center;
            width: 22px;
            height: 22px;
            background: url('~@/assets/contest/pre.png') no-repeat center;
            background-size: 100% 100%;
            transition: all 0.4s;
            &:hover {
              background: url('~@/assets/contest/next.png') no-repeat center;
              background-size: 100% 100%;
              transform: rotate(-180deg);
            }
          }
          .el-button-group > .el-button:last-child {
            border: none;
            align-self: center;
            width: 22px;
            height: 22px;
            background: url('~@/assets/contest/pre.png') no-repeat center;
            transform: rotate(180deg);
            background-size: 100% 100%;
            transition: all 0.4s;
            &:hover {
              background: url('~@/assets/contest/next.png') no-repeat center;
              background-size: 100% 100%;
              transform: rotate(360deg);
            }
          }

          .el-button-group > .el-button:first-child span,
          .el-button-group > .el-button:last-child span {
            display: none;
          }
        }
        .el-calendar__body {
          padding: 0;
          .el-calendar-table {
            thead {
              height: 40px;
              background: #cfebec;
              th:before {
                content: '周';
              }
            }
            td {
              .get-day {
                text-align: center;
                font-weight: 500;
                color: #9a9a9a;
              }
            }
            .is-today {
              .get-day {
                color: #ff8f2e;
                font-weight: 500;
              }
            }
          }
        }
        .el-calendar-day:hover {
          background-color: transparent;
        }
        .el-calendar-day {
          background-color: transparent;
          min-height: 85px;
          height: 100%;
          padding: 0;
        }
        .el-calendar-table td.is-today {
          background: #fff;
          .itemdate {
            background: #fff5eb;

            i {
              background: #ff8f2e;
            }
          }
          .item {
            &::before {
              content: '今日';
              font-size: 18px;
              font-family: PingFangSC-Medium, PingFang SC;
              font-weight: 500;
              color: #ff8f2e;
              text-align: center;
              margin-bottom: 10px;
            }
          }
          .day {
            display: none;
          }
        }
        .el-calendar-table td {
          border-bottom: 1px solid #ddd;
          border-right: 1px solid #ddd;
        }
        // .el-calendar-table:not(.is-range) td.next {
        //   /*隐藏下个月的日期*/
        //   visibility: hidden;
        // }

        // .el-calendar-table:not(.is-range) td.prev {
        //   /*隐藏上个月的日期*/
        //   visibility: hidden;
        // }
      }
    }
  }
}
举报

相关推荐

0 条评论