vue日历组件

在这里插入图片描述

<template>
  <div class="Calendar">
    <Header />
    <DateList />
    <div style="overflow: hidden;">
      <div
        @touchstart="touchstart"
        @touchend="touchend"
        @touchmove="touchmove"
        ref="wrapper"
        class="wrapper"
      >
        <span v-for="(item, index) in 12" :key="index">
          <MonthList
            :month="index + 1"
            :currentMonth="currMonth"
          />
          <DateGrid
            :index="index + 1"
            :currentMonth="currMonth"
            :currentDay="currDay"
            :currentDate="currDate"
            :currentYear="currYear"
          />
        </span>
      </div>
    </div>
  </div>
</template>

<script>
import Header from "../components/calendar/Header";
import DateList from "../components/calendar/DateList";
import MonthList from "../components/calendar/MonthList";
import DateGrid from "../components/calendar/DateGrid";
export default {
  data() {
    return {
      currYear: 0,
      currMonth: 0,
      currDate: 0,
      currDay: 0,
      endY: 0,
      startY: 0,
      offsetH: 0,
      datelistHeight: 0,
    };
  },
  mounted() {
    this.currentDate();
    this.offsetH = this.$refs.wrapper.clientHeight;
    this.datelistHeight = this.$children[1].$refs.cont.clientHeight;
  },
  methods: {
    // 获取当前月份对应展示的日历,让它滚动到视图上方
    shouldMonth() {
      let shouldNode = this.$refs.wrapper.children[this.currMonth - 1];
      this.endY = -shouldNode.offsetTop;
      // this.endY = -(shouldNode.offsetTop + this.datelistHeight);
      this.$refs.wrapper.style.transform = `translateY(${this.endY}px)`;
      setTimeout(() => {
        this.$refs.wrapper.style.transition = "none";
      }, 200);
    },
    //获取当前日期
    currentDate() {
      let d = new Date();
      this.currYear= d.getFullYear(); // 年
      this.currMonth = d.getMonth() + 1; // 月
      this.currDate = d.getDate(); // 日
      this.currDay = d.getDay(); // 星期

      this.shouldMonth();
    },
    //日历可拖动
    touchstart(e) {
      this.startY = e.changedTouches[0].screenY;
    },
    touchmove(e) {
      let disY = this.endY + (e.touches[0].screenY - this.startY);
      if (disY >= 0) {
        disY = 0;
      }
      if (disY <= -this.offsetH) {
        disY = this.offsetH;
      }
      this.$refs.wrapper.style.transform = `translateY(${disY}px)`;
    },
    touchend() {
      let trans = window.getComputedStyle(this.$refs.wrapper)["transform"];
      this.endY = parseFloat(trans.split(",").pop());
    },
  },
  components: {
    Header,
    DateList,
    MonthList,
    DateGrid,
  },
};
</script>

<style lang="less" scoped>
.Calendar {
  width: 100vw;
  height: 100vh;
  box-sizing: border-box;
  overflow: hidden;

  .wrapper {
    width: 100vw;
    padding-bottom: 5vh;
    transform: translateY(0px);
    z-index: -1;
    transition: 0.3s;
  }
}
</style>

<template>
  <div class="DateGrid flex">
    <span class="grid" v-for="(item, index) in 35" :key="index">
      <div v-if="index < currMonthFirstDay" class="Highlight-text">
        <span> </span>
      </div>
      <div
        v-if="
          index >= currMonthFirstDay &&
          index < currMonthLastDate + currMonthFirstDay
        "
        class="Highlight-text date"
        :class="gridItemIndex == index? 'clickStyle' : ''"
        @click="gridItemIndex = index"
      >
        {{ index - currMonthFirstDay + 1 }}
      </div>
    </span>
  </div>
</template>

<script>
export default {
  props: {
    currentYear: Number,
    currentMonth: Number,
    currentDay: Number,
    currentDate: Number,
    index: Number,
  },
  data() {
    return {
      currMonthFirstDay: 0,
      currMonthLastDate: 0,
      gridItemIndex: -1
    };
  },
  mounted() {
    this.mountedDone();
    this.currMonthDate();
  },
  methods: {
    // 当前月分的第一天和最后一天的星期,及对应的号
    currMonthDate() {
      let currMonthHeader = new Date(`${this.currentYear}-${this.index + 1}-1`);
      let currMonthFooter = new Date(this.currentYear, this.index, 0);
      this.currMonthFirstDay = currMonthHeader.getDay(); // 当前月第一天的星期
      this.currMonthLastDate = currMonthFooter.getDate(); // 这个月一共多少天

      this.$el.previousSibling.style.transform = `translateX(${
        (this.currMonthFirstDay + 0.5) * 13.7
      }vw)`;
    },
    mountedDone() {
      setTimeout(() => {
        // console.log(
        //   `${this.currentMonth}月 ${this.currentDate}日 星期${this.currentDay}`
        // );
        let all = document.getElementsByClassName("DateGrid");
        all[this.currentMonth - 1].children[this.currentDate + 1].className =
          "grid Highlight-container";
      }, 100);
    },
  },
};
</script>

<style lang="less" scoped>
@import "../../styles/flex.css";
.DateGrid {
  height: 35vh;
  width: 100vw;
  box-sizing: border-box;
  padding: 0 2vw;
  flex-wrap: wrap;

  .grid {
    width: calc(96vw / 7);
    text-align: center;
    box-sizing: border-box;
    padding: 0 1vw;

    .date{
      height: 100%;
      font-size: 1.2em;
      display: flex;
      justify-content: center;
      align-items:center;
    }
    .clickStyle{
      background-color: #f77;
      color: #fffae5;
    }
    
  }
  .Highlight-container {
    .Highlight-text {
      background-color: #f12;
      height: 100%;
      color: #fff;
      padding: 0 1vw;
    }
  }
  .clickDataHighlight {
    background-color: #f66;
  }
}
</style>

<template>
  <div ref='cont' class="DateList">
    <span v-for="(x,i) in list" :key="i">
      {{ x }}
    </span>
  </div>
</template>

<script>
export default {
  data() {
    return {
      list:['一','二','三','四','五','六','日']
    }
  },
}
</script>

<style lang="less" scoped>
.DateList{
  height: 3.5vh;
  width: 90vw;
  background-color: #eee;
  box-sizing: border-box;
  border-radius: 3vh;
  color: #555;
  margin-bottom: 0.5vw;
  display: flex;
  justify-content: space-evenly;
  align-items: center;
  margin-left: 5vw;
}
</style>
<template>
  <div class="calendar-header flex align-center">
  <span class="arrow" v-text="arrow"></span>
  <h3>选择日期</h3>
  </div>
</template>

<script>
export default {
  data() {
    return {
      arrow: '<'
    }
  },
}
</script>

<style lang="less" scoped>
@import '../../styles/flex.less';
.calendar-header{
  height: 7vh;
  width: 100vw;
  background-color: #fff;
  box-sizing: border-box;
  padding: 0 10px;
  overflow: hidden;
  z-index: 9;

  h3{
    margin-left: 50%;
    transform: translateX(-50%);
  }

  .arrow{
    display: inline-block;
    transform: scale(1,1.5);
    font-weight: bold;
  }
}
</style>
<template>
  <div class="MonthList"
  >
    <p>{{ month || 0 }}</p>
  </div>
</template>

<script>
export default {
  props: {
    month: Number,
    currentMonth: Number
  },
};
</script>

<style lang="less" scoped>
.MonthList {
  height: 4vh;
  width: 100vw;
  border-bottom: 1px solid #eee;
  text-align: left;
  font-size: 1.4em;
  font-weight: bold;
  box-sizing: border-box;
  margin: 2vh 0 1vh 0;
  text-indent: 1vw;
}
</style>

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值