Vant日历组件实现点击左右按钮切换月份

一 Calendar 日历

在这里插入图片描述
在这里插入图片描述
Vant4.x版本提供了switch-mode属性,里面刚好可以满足我们的需求,但适用于Vue3开发,所以我们还得自己动手。先看一下Calendar里面的属性

参数说明类型默认值
type选择类型:single表示选择单个日期,multiple表示选择多个日期,range表示选择日期区间stringsingle
title日历标题string日期选择
color主题色,对底部按钮和选中日期生效string#ee0a24
min-date可选择的最小日期Date当前日期
max-date可选择的最大日期Date当前日期的六个月后
default-date默认选中的日期,type 为 multiple 或 range 时为数组,传入 null 表示默认不选择DateDate[]
row-height日期行高numberstring
formatter日期格式化函数(day: Day) => Day-
poppable是否以弹层的形式展示日历booleantrue
lazy-render是否只渲染可视区域的内容booleantrue
show-mark是否显示月份背景水印booleantrue
show-title是否展示日历标题booleantrue
show-subtitle是否展示日历副标题(年月)booleantrue
show-confirm是否展示确认按钮booleantrue
readonly是否为只读状态,只读状态下不能选择日期booleantrue
confirm-text确认按钮的文字string确定
confirm-disabled-text确认按钮处于禁用状态时的文字string确定
first-day-of-week设置周起始日0-60

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

二 需求

如图所示只显示一个月份,页面上通过点击左右按钮来实现对月份的切换。实现是将min-date设置月份的第一天,max-date设置为月份的最后一天

在这里插入图片描述

三 完整代码

  <div class="main-clock-calendar">
      <div class="main-clock-calendar-title">签到详情</div>
      <div class="calendar-div">
        <van-calendar
          :poppable="false"
          :show-subtitle="false"
          :show-confirm="false"
          type="multiple"
          :min-date="minDate"
          :max-date="maxDate"
          :default-date="defaultDate"
          first-day-of-week="1"
          lazy-render
          show-subtitle
          readonly
        >
          <div slot="title" class="title-box">
            <div @click="arrowLeft(1)"><img class="title-box-left" src="@/assets/clock/left.png" alt=""></div>
            {{ calendarTitle }}
            <div @click="arrowRight(1)"><img class="title-box-right" src="@/assets/clock/right.png" alt=""></div>
          </div>
        </van-calendar>
      </div>
    </div>
   getClient() {
      this.$store.dispatch('clock/requestQueryClockClient', {clockId: this.clockId})
        .then((data) => {
          this.client = data
          const nowTime = new Date()
          const year = nowTime.getFullYear()
          const month = nowTime.getMonth()
          this.calendarTitle = year + '年' + (month + 1) + '月'
          this.minDate = new Date(year, month, 1)
          this.maxDate = new Date(year, month + 1, 0)
          this.isClock = isToday(data.recentClockInTime)
          this.getClockTask()
          this.getClockInTime()
          this.initEnterClientTag()
        })
    },
    //获取客户的打卡时间,将打卡时间都转化成date类型,再push到default-date数组中
    getClockInTime() {
      this.$store.dispatch('clock/requestQueryClockInTime', {clockId: this.clockId})
        .then((data) => {
          data.forEach((item => {
            const nowDay = new Date(item)
            const year = nowDay.getFullYear()
            const month = nowDay.getMonth()
            const day = nowDay.getDate()
            this.defaultDate.push(new Date(year, month, day))
          }))
        })
    },
    arrowLeft(e) {
      let nowTime = new Date(this.minDate)
      let year = nowTime.getFullYear()
      let month = nowTime.getMonth() - e
      if ((month + 1) === 0) {
        this.calendarTitle = (year - 1) + '年' + (12) + '月'
      } else {
        this.calendarTitle = year + '年' + (month + 1) + '月'
      }
      this.minDate = new Date(year, month, 1)
      this.maxDate = new Date(year, month + 1, 0)
    },
    arrowRight(e) {
      let nowTime = new Date(this.minDate)
      let year = nowTime.getFullYear()
      let month = nowTime.getMonth() + e
      if (month + 1 > 12) {
        this.calendarTitle = (year + 1) + '年' + (1) + '月'
      } else {
        this.calendarTitle = year + '年' + (month + 1) + '月'
      }
      this.minDate = new Date(year, month, 1)
      this.maxDate = new Date(year, month + 1, 0)
    },

css 部分

.main-clock-calendar {
    width: 8.933rem;
    height: 9.3rem;
    opacity: 1;
    background: url('../../assets/clock/calendar-bgc.png');
    background-size: 100% 100%;
    margin: 0.427rem 0.533rem 0.533rem 0.533rem;

    .main-clock-calendar-title {
      font-size: 0.373rem;
      font-family: PingFang SC-Medium, PingFang SC, sans-serif;
      font-weight: 500;
      color: #000000;
      line-height: 0.48rem;
      padding: 0.533rem 0 0 0.32rem;
    }

    .calendar-div {
      ::v-deep .van-calendar {
        height: 7.8rem !important;
        margin-top: 0.233rem;
      }

      ::v-deep .van-calendar__days {
        align-items: center;
        justify-content: flex-end;
      }

      ::v-deep .van-calendar__day--start {
        width: 0.64rem;
        height: 0.64rem !important;
        background: #FE6651;
        margin: 0.31rem;
        box-sizing: border-box;

        border-radius: 0.107rem 0.107rem 0.107rem 0.107rem;
        opacity: 1;
      }

      ::v-deep .van-calendar__day--multiple-middle {
        width: 0.64rem;
        height: 0.64rem !important;
        background: #FE6651;
        margin: 0.31rem;
        box-sizing: border-box;
        border-radius: 0.107rem 0.107rem 0.107rem 0.107rem;
        opacity: 1;
      }

      ::v-deep .van-calendar__day--end {
        width: 0.64rem;
        height: 0.64rem !important;
        background: #FE6651;
        margin: 0.31rem;
        box-sizing: border-box;
        border-radius: 0.107rem 0.107rem 0.107rem 0.107rem;
        opacity: 1;
      }

      ::v-deep .van-calendar__day {
        height: 0.967rem;
      }

      ::v-deep .van-calendar__header-subtitle {
        font-size: 0.48rem;
        font-family: PingFang SC-Medium, PingFang SC, sans-serif;
        font-weight: 500;
        color: #000000;
        line-height: 0.96rem;
      }

      ::v-deep .van-calendar__header {
        box-shadow: 0 2px 5px rgba(125, 126, 128, .16) !important;
      }

      .van-icon-cross::before {
        content: '';
      }

      ::v-deep .van-calendar__day--multiple-selected {
        width: 0.64rem;
        height: 0.64rem !important;
        background: #FE6651;
        margin: 0 3.3%;
        border-radius: 0.107rem 0.107rem 0.107rem 0.107rem;
        opacity: 1;
      }

      ::v-deep .van-calendar__header-subtitle {
        display: none;
      }

      .title-box {
        display: flex;
        justify-content: space-between;

        .title-box-left {
          width: 0.32rem;
          height: 0.32rem;
          margin-left: 0.32rem;
          cursor: pointer;
        }

        .title-box-right {
          width: 0.32rem;
          height: 0.32rem;
          margin-right: 0.32rem;
          cursor: pointer;
        }
      }
    }
    ::v-deep .van-calendar__day:last-child {
      margin-right: auto!important;
    }
  }
  • 17
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值