preface
The project required, there was no proper wheel, so…
Effect (circled in red) :
demand
- The date is displayed corresponding to the week
- An optional default selected date
- Disabled today and before
- A product is prohibited within the shortest scheduled time, such as three days in advance, it is prohibited today, tomorrow and the day after tomorrow
- The corresponding price is shown below the date
- Easy version: It needs to be perfected if it is to be considered a full calendar
Train of thought
-
Pass in the year and month to create a calendar; Date price array; Date disabled array
-
Create a two-dimensional array with the number of weeks in a month in the first dimension and the number of days in the second dimension. A one-dimensional cycle number has at most six arrays
-
Each date contains three attributes: year, month and day. The date corresponding to the price is also year, month and day. The disabled date page is based on year, month and day
-
New Date(‘2019/06/21’) passes in a Date, which can be used to determine whether a certain month has a certain day. If not, return the constructor for the first of the following month; Returns the constructor for that day, if any; Values beyond 31 are Invalid.
// Gets the year, month and day from the date constructor passed in getYMD(time = new Date()) { return { _year: time.getFullYear(), _month: time.getMonth() + 1._date: time.getDate(), } }, // Verify that the date is valid: the corresponding month has the date validDate(year, month, date) { let time = new Date(`${year}/${month}/${date}`); const { _year, _month, _date } = this.getYMD(time); return _year === year && month === _month && date === _date }, Copy the code
Generates an array split by week for the number of days of the month
// Generate the number of days in a month generateCalendar(year, month) { let that = this; let weekLen = new Array(7).fill(' '); // Seven days a week let weekday = new Date(`${year}/${month}/ 01 `).getDay(); // What day is the first / / reset this.monthDay = [[], [], [], [], [], []]; // Generates the number of aligned days of the week in January, starting with Sunday weekLen.map((item, index) = > { that.monthDay[0].push( index < weekday ? ' ' : (index === weekday) ? {year, month, date: 1} : {year, month, date: that.monthDay[0][index- 1].date+1}); that.monthDay[1].push({year, month, date: index + (7 - weekday + 1)}); that.monthDay[2].push({year, month, date: that.monthDay[1][index].date + 7}); that.monthDay[3].push({year, month, date: that.monthDay[2][index].date + 7}); if ( that.monthDay[3][index].date + 7< =31 && that.validDate(year, month, that.monthDay[3][index].date + 7) ) { that.monthDay[4].push({year, month, date: that.monthDay[3][index].date + 7}); } else { that.monthDay[4].push(' '); } if ( that.monthDay[4][index].date + 7< =31 && that.validDate(year, month, that.monthDay[4][index].date + 7) ) { that.monthDay[5].push({year, month, date: that.monthDay[4][index].date + 7}); }})}Copy the code
Problems encountered:
- This is on the Android App (WebView),
new Date('2019/06/21')
A forward slash is required for arguments to'/'
Use a dash linenew Date('2019-06-21')
“Invalid Date” will be used for IOS'/'
In terms of compatibility'/'
The most reliable…
code
Parent component use
<cus-calendar
class="calendar"
:year="monthActive.year"
:month="monthActive.month"
:dateActiveDefault="activeDate"
:saleList="saleList"
:disabledDate="disabledDate"
@check-date="checkDate"
/>
Copy the code
Other:
this.disabledDate = ['2019-06-21'.'2019-06-22'.'2019-06-23'];
this.saleList = [
{ date: '2019-06-24'.price: 6188 },
{ date: '2019-06-25'.price: 6188 },
{ date: '2019-06-26'.price: 6188 },
{ date: '2019-07-26'.price: 6188 },
{ date: '2019-06-27'.price: 6188 },
{ date: '2019-06-28'.price: 6188},];Copy the code
template
<template>
<view class="calendar-container">
<view class="month-bg">
{{ month }}
</view>
<view class="week-title">
<text class="weekend">day</text>
<text>one</text>
<text>two</text>
<text>three</text>
<text>four</text>
<text>five</text>
<text class="weekend">six</text>
</view>
<view class="calendar-content">
<view
v-for="(week, weekindex) in monthDay"
:key="weekindex"
class="week-month"
>
<view
class="date"
v-for="(date, dateindex) in week"
:key="dateindex"
:class="{'date-disabled': ! date || beforeToday(date) || disabledDateFn(date)}"
@tap="dateTap(date)"
>
<view
class="date-item"
:class="{ 'date-active': showPrice(date) && isActiveDate(date), 'date-active date-active2': ! showPrice(date) && isActiveDate(date) }"
>
<text v-if="isToday(date)">today</text>
<text v-else>{{ date.date }}</text>
<view class="price" v-if="showPrice(date)">Selections {{showPrice (date)}}</view>
</view>
</view>
</view>
</view>
</view>
</template>
Copy the code
js
// <script>
// Travel products - calendar
export default {
name: 'cus-calendar'.props: {
theme: {
type: String.default: '#F87D72'
},
// The price below the date
saleList: {
type: Array.default: (a)= >[]},// Disable the date
disabledDate: {
type: Array.default: (a)= >[]},// The default selected date, such as 2019-06-24
dateActiveDefault: {
type: String.default: ' '
},
year: {
type: Number.default: (a)= > new Date().getFullYear()
},
month: {
type: Number.default: (a)= > new Date().getMonth()+1
}
},
data() {
return {
newYear: ' '.newMonth: ' '.monthDay: [[], [], [], [],dateActive: {
year: ' '.month: ' '.date: ' '
}
}
},
mounted() {
// It is selected by default
if (this.dateActiveDefault) {
const [year, month, date] = this.dateActiveDefault.split(The '-');
this.dateActive = {
year: +year,
month: +month,
date: +date
}
}
},
watch: {
month: {
handler(val) {
this.newYear = this.year;
this.newMonth = this.month;
this.generateCalendar(this.newYear, this.newMonth);
},
immediate: true}},methods: {
// Gets the year, month and day from the date constructor passed in
getYMD(time = new Date()) {
return {
_year: time.getFullYear(),
_month: time.getMonth() + 1._date: time.getDate(),
}
},
// Verify that the date is valid: the corresponding month has the date
validDate(year, month, date) {
let time = new Date(`${year}/${month}/${date}`);
const { _year, _month, _date } = this.getYMD(time);
return _year === year && month === _month && date === _date
},
// Is it today
isToday({ year, month, date }) {
let time = new Date(a);const { _year, _month, _date } = this.getYMD(time);
return year === _year && month === _month && date === _date
},
// Before today
beforeToday({ year, month, date }) {
let time = new Date(a);const { _year, _month, _date } = this.getYMD(time);
return year <= _year && month <= _month && date <= _date
},
// Disable the date
disabledDateFn({ year, month, date }) {
month = (month+' ').padStart(2.'0');
date = (date+' ').padStart(2.'0');
return this.disabledDate.includes(`${year}-${month}-${date}`);
},
// Whether it is selected
isActiveDate({ year, month, date }) {
const { year: _year, month: _month, date: _date } = this.dateActive;
return year === _year && month === _month && date === _date;
},
// Click valid day
dateTap({ year, month, date }) {
this.dateActive = {
year,
month,
date
};
this.$emit('check-date'.this.dateActive);
},
// The price is shown below the date
showPrice({ year, month, date }) {
if(! year)return;
month = (month+' ').padStart(2.'0');
date = (date+' ').padStart(2.'0');
let obj = this.saleList.find(item= > item.date === `${year}-${month}-${date}`);
return obj && obj.price
},
// Generate the number of days in a month
generateCalendar(year, month) {
let that = this;
let weekLen = new Array(7).fill(' '); // Seven days a week
let weekday = new Date(`${year}/${month}/ 01 `).getDay(); // What day is the first
/ / reset
that.monthDay = [[], [], [], [], [], []];
// Generates the number of aligned days of the week in January, starting with Sunday
weekLen.map((item, index) = > {
that.monthDay[0].push(
index < weekday
? ' '
: (index === weekday)
? {year, month, date: 1}
: {year, month, date: that.monthDay[0][index- 1].date+1}); that.monthDay[1].push({year, month, date: index + (7 - weekday + 1)});
that.monthDay[2].push({year, month, date: that.monthDay[1][index].date + 7});
that.monthDay[3].push({year, month, date: that.monthDay[2][index].date + 7});
if (
that.monthDay[3][index].date + 7< =31 &&
that.validDate(year, month, that.monthDay[3][index].date + 7)
) {
that.monthDay[4].push({year, month, date: that.monthDay[3][index].date + 7});
} else {
that.monthDay[4].push(' ');
}
if (
that.monthDay[4][index].date + 7< =31 &&
that.validDate(year, month, that.monthDay[4][index].date + 7)
) {
that.monthDay[5].push({year, month, date: that.monthDay[4][index].date + 7}); }})}}}// </script>
Copy the code
style
/* <style lang="scss" scoped> */
.calendar-container {
width: 100%;
position: relative;
color: # 999;
}
.month-bg {
position: absolute;
top: 50%;
left: 50%;
color: #f6f6f6;
font-size: 60px;
transform: translate(-50%, -50%);
z-index: -1;
}
.week-title {
padding: 20upx 40upx;
display: flex;
justify-content: space-between;
&>text {
flex: 1;
text-align: center; }}.weekend {
color: #F87D72;
}
.week-month {
display: flex;
justify-content: flex-start;
padding: 20upx 40upx;
color: #2b2b2b; & >.date {
flex: 14.285% 0 0;
text-align: center; }}.date-item {
width: 60upx;
height: 60upx;
position: relative;
left: 50%;
margin-left: -30upx;
line-height: 1;
}
.date-disabled {
color: # 999;
pointer-events: none;
}
.price {
color: #F87D72;
font-size: 18upx;
}
.date-active {
color: #fff;
&::after {
content: ' ';
width: 140%;
height: 140%;
display: block;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 50px;
background: linear-gradient(right, #F87D72.#F29E97);
box-shadow: 0 6upx 16upx -6upx #F97C71;
z-index: -1; } & >.price {
color: #fff; }}.date-active2::after {
transform: translate(-50%, -68%);
}
/* </style> */
Copy the code