
<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.$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(() => {
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>