vant Calendar组件自定义

在这里插入图片描述
使用场景:左右箭头可以切换年,上个月和下个月可以切换月份,左侧日期显示同步变化,当天是橘色的那个颜色,其他的需要传数组,看哪天有数据需要在日历上打那个蓝色的点儿
源码:

<template>
  <div class="calendar">
    <van-calendar class="calendar-main" :min-date="minDate" :max-date="maxDate" :poppable="false" :show-confirm="false"
      :show-mark="false" :default-date="defaultDate" first-day-of-week="1" row-height="35px" :formatter="formatter"
      ref="calendar">
      <template #title>
        <div class="calendar-top">

          <div class="calendar-top-time">
            {{ year }}年{{ month + 1 }}月
          </div>
          <div class="calendar-top-button">
            <van-icon name="arrow-left" class="button-icon" @click="arrowLeft()" />

            <div :style="{ color: isClickLastYear ? '' : 'grey' }" @click="lastYear">上个月</div>
            <div @click="currentYear">本月</div>
            <div :style="{ color: isClickNextYear ? '' : 'grey' }" @click="nextYear">下个月</div>
            <van-icon name="arrow" class="button-icon" @click="arrowRight()" />
          </div>
        </div>
      </template>
    </van-calendar>
  </div>
</template>

<script>
export default {
  data () {
    return {
      defaultDate: null,
      today: new Date(),
      year: new Date().getFullYear(),
      month: new Date().getMonth(),
      minDate: null,
      maxDate: null,
      isClickLastYear: true,
      isClickNextYear: true,
      dayDatas:['2024-11-1']
    }
  },
  created () {

    this.year = this.today.getFullYear()
    this.month = this.today.getMonth()
    this.setDate()
  },
  methods: {
    formatter (day) {
      //给有数据的日期加点
      if (this.dayDatas && this.dayDatas.length > 0) {
        this.dayDatas.forEach(item => {
          if (new Date(item).getTime() == day.date.getTime()) {
            day.className = "addDot"
          }
        })
      }
      //当天日期加样式
      if (day.date.toDateString() == this.today.toDateString()) {
        day.className = "calendarToday"
      }
      return day
    },
    //设置当前显示日历
    setDate () {
      const daycount = new Date(this.year, this.month + 1, 0).getDate()
      let monthMin = new Date(this.year, this.month, 1)
      let monthMax = new Date(this.year, this.month, daycount)
      this.minDate = monthMin
      this.maxDate = monthMax
    },
    //切换上年
    arrowLeft () {
      this.year--
      this.setDate()
    },
    //切换上月
    lastYear () {

      if (this.month > 0) {
        this.month--
        this.setDate()
        if (this.month > 0) {
          this.isClickLastYear = true
        } else {
          this.isClickLastYear = false
        }
        if (!this.isClickNextYear) {
          this.isClickNextYear = true
        }
      }

    },
    //切换下年
    arrowRight () {
      this.year++
      this.setDate()
    },
    //切换下月
    nextYear () {

      if (this.month < 11) {
        this.month++
        this.setDate()
        if (this.month < 11) {
          this.isClickNextYear = true
        } else {
          this.isClickNextYear = false
        }
        if (!this.isClickLastYear) {
          this.isClickLastYear = true
        }

      }

    },
     currentYear () {
      this.month = this.today.getMonth()
      this.setDate()
    }
  }
}
</script>


<style lang="less" scoped>
.calendar {
  // border: 1px solid red;
  margin-bottom: 46px !important;

  .calendar-top {
    margin-bottom: 16px;
    display: flex;
    justify-content: space-between;

    .calendar-top-time {
      color: #000;
      margin: 0 10px;
    }

    .calendar-top-button {
      display: flex;
      font-size: 14px;
      align-items: center;
      gap: 8px;
      color: #59afff;

      .button-icon {
        width: 16px;
        height: 16px;
        line-height: 16px;
        background: #d9e6ff;
        border-radius: 50%;
      }


    }
  }

  .calendar-weekdays {
    display: flex;
    height: 50px;
    justify-content: space-between;
    align-items: center;

    // border: 1px solid red;
    .calendar-weekdays-item {
      width: 50px;
      font-size: 20px;
      color: rgba(0, 0, 0 0.5);
      // border: 1px solid red
    }
  }

  .calendar-days {
    display: grid;
    grid-template-columns: repeat(7, 8%);
    grid-row-gap: 14px;
    height: 50px;
    justify-content: space-between;
    align-items: center;

    .calendar-days-item {
      flex-shrink: 0;
      width: 50px;
      font-size: 28px;
      color: #000000;
      // border: 1px solid red;
    }
  }
}

/deep/.van-calendar {
  width: 100%;
  margin-left: -3%;
  background: none;
}

/deep/.van-calendar__body {
  overflow: hidden;
}

/deep/.van-calendar__header {
  box-shadow: none;
}

// /deep/(.van-calendar__day) {
//   margin-bottom: 6px !important;
// }
/deep/.van-calendar__selected-day {
  border-radius: 50%;
  background-color: #59afff;
  // background-color: #ffae34;
  z-index: 2;
  position: absolute;
}

/deep/.van-calendar__selected-day::after {
  background-color: #fff !important;
}

/deep/.van-calendar__header-subtitle {
  display: none !important;
}

/deep/.van-calendar__weekday {
  color: rgba(0, 0, 0 0.5);
}

/deep/.van-calendar__weekday::before {
  content: "周";
  color: rgba(0, 0, 0 0.5);
}

//有数据日期加点
/deep/.addDot {
  position: relative;
}

/deep/.addDot::after {
  position: absolute;
  content: "";
  width: 6px;
  height: 6px;
  top: 28Px;
  // left: 45px;
  border-radius: 50%;
  background-color: #0084ff;
}

// 当天日期
/deep/.calendarToday {
  position: relative;
  color: #fff;
  // font-size: 0;
  // z-index: 1;
}

/deep/.calendarToday::before {
  width: 35Px;
  height: 35Px;
  line-height: 35Px;
  position: absolute;
  top: 0;
  content: "今";
  text-align: center;
  font-size: 15px;
  border-radius: 50%;
  background-color: #ffae34;
  // z-index: -1;
}

//当天日期并且有数据
/deep/.addDot_calendarToday::after {
  position: absolute;
  content: "";
  width: 12px;
  height: 12px;
  top: 26Px;
  left: 45px;
  border-radius: 50%;
  background-color: #fff;
  z-index: 4;
}

/deep/.addDot_calendarToday::before {
  width: 35Px;
  height: 35Px;
  line-height: 35Px;
  position: absolute;
  top: 0;
  content: "今";
  text-align: center;
  font-size: 15px;
  border-radius: 50%;
  color: #fff;
  background-color: #ffae34;
}

//有数据并且被选中
/deep/.addDot_Select::after {
  position: absolute;
  content: "";
  width: 12px;
  height: 12px;
  top: 26Px;
  left: 45px;
  border-radius: 50%;
  background-color: #fff;
  z-index: 3;
}

//被选中显示的今字
/deep/.calendarToday .van-calendar__selected-day {
  font-size: 0;
}

/deep/.calendarToday .van-calendar__selected-day::before {
  content: "今";
  z-index: 9;
  font-size: 15px;
  height: 35Px;
  line-height: 35Px;

}

/deep/.addDot_calendarToday .van-calendar__selected-day {

  font-size: 0;
}

/deep/.addDot_calendarToday .van-calendar__selected-day::before {
  content: "今";
  z-index: 9;
  font-size: 15px;
  height: 35Px;
  line-height: 35Px;
}
</style>

参考文章:https://blog.youkuaiyun.com/weixin_46687032/article/details/126508816?spm=1001.2014.3001.5501

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值