vue/uni-app之空手撕日历
栏目: JavaScript · 发布时间: 5年前
内容简介:项目需要,没有合适的轮子,所以,,,效果(红圈部分):缩进变成4空格了。。。
项目需要,没有合适的轮子,所以,,,
效果(红圈部分):
需求
- 日期对应星期显示
- 今天包括今天之前禁用
- 某产品的最短预定时间内禁用,如提前三天,则今天明天后天禁用
- 日期下面显示对应的价格
- 简易版: 如果要当成完全的日历,还需完善
思路
-
传入年份,月份创建日历;日期价格数组;日期禁用数组
-
创建一个二维数组,第一维存放一月的周树,第二维存放一周的天数;一维的周树最多有七个数组
-
每个日期包含年月日三个属性,价格对应的日期也是年月日,禁用的日期页按照年月日,所以匹配一下就可以了
-
每月天数使用 js 原生判断,即:
js 中
new Date('2019-06-21')
传入一个日期,可以用来判断某个月是否有某一天。没有的话,返回下一个月一号的构造函数;有的话返回这一天的构造函数;超出31号的则是Invalid
// 验证日期是否有效:对应的月份是否有这一天 validDate(year, month, date) { let time = new Date(`${year}-${month}-${date}`); let _year = time.getFullYear(); let _month = time.getMonth() + 1; let _date = time.getDate(); return _year === year && month === _month && date === _date } 复制代码
生成当月天数按周分割的数组
// 生成一个月的天数 generateCalendar(year, month) { let that = this; let weekLen = new Array(7).fill(''); // 一周七天 let weekday = new Date(`${year}-${month}-01`).getDay(); // 1号星期几 // 重置 this.monthDay = [[], [], [], [], [], []]; // 生成一月对齐星期的天数,一周以周日开始 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 && this.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 && this.validDate(year, month, that.monthDay[4][index].date + 7) ) { that.monthDay[5].push({year, month, date: that.monthDay[4][index].date + 7}); } }) } 复制代码
代码
缩进变成4空格了。。。
父组件使用
<cus-calendar class="calendar" :year="monthActive.year" :month="monthActive.month" :saleList="saleList" :disabledDate="disabledDate" @check-date="checkDate" /> 复制代码
其他:
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 }, ]; 复制代码
template
<template> <view class="calendar-container"> <view class="month-bg"> {{ month }} </view> <view class="week-title"> <text class="weekend">日</text> <text>一</text> <text>二</text> <text>三</text> <text>四</text> <text>五</text> <text class="weekend">六</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': 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)">今天</text> <text v-else>{{ date.date }}</text> <view class="price" v-if="showPrice(date)">¥{{ showPrice(date) }}</view> </view> </view> </view> </view> </view> </template> 复制代码
js
// 旅游产品 - 日历 export default { name: 'cus-calendar', props: { theme: { type: String, default: '#F87D72' }, saleList: { type: Array, default: () => [] }, disabledDate: { type: Array, default: () => [] }, year: { type: Number, default: () => new Date().getFullYear() }, month: { type: Number, default: () => new Date().getMonth()+1 } }, data() { return { newYear: '', newMonth: '', monthDay: [[], [], [], [], [], []], dateActive: { year: '', month: '', date: '' } } }, watch: { month: { handler(val) { this.newYear = this.year; this.newMonth = this.month; this.generateCalendar(this.newYear, this.newMonth); }, immediate: true } }, methods: { // 验证日期是否有效:对应的月份是否有这一天 validDate(year, month, date) { let time = new Date(`${year}-${month}-${date}`); let _year = time.getFullYear(); let _month = time.getMonth() + 1; let _date = time.getDate(); return _year === year && month === _month && date === _date }, // 是否今天 isToday({ year, month, date }) { let time = new Date(); let _year = time.getFullYear(); let _month = time.getMonth() + 1; let _date = time.getDate(); return year === _year && month === _month && date === _date }, // 今天之前 beforeToday({ year, month, date }) { let time = new Date(); let _year = time.getFullYear(); let _month = time.getMonth() + 1; let _date = time.getDate(); return year <= _year && month <= _month && date <= _date }, // 禁用的日期 disabledDateFn({ year, month, date }) { month = month < 10 ? (month+'').padStart(2, '0') : month; date = date < 10 ? (date+'').padStart(2, '0') : date; return this.disabledDate.includes(`${year}-${month}-${date}`); }, // 是否选中 isActiveDate({ year, month, date }) { const { month: _month, date: _date } = this.dateActive; return month === _month && date === _date; }, // 点击有效的一天 dateTap({ year, month, date }) { this.dateActive = { year, month, date }; this.$emit('check-date', this.dateActive); }, // 日期下面显示价格 showPrice({ year, month, date }) { if (!year) return; month = month < 10 ? (month+'').padStart(2, '0') : month; date = date < 10 ? (date+'').padStart(2, '0') : date; let obj = this.saleList.find(item => item.date === `${year}-${month}-${date}`); return obj && obj.price }, // 生成一个月的天数 generateCalendar(year, month) { let that = this; let weekLen = new Array(7).fill(''); // 一周七天 let weekday = new Date(`${year}-${month}-01`).getDay(); // 1号星期几 // 重置 this.monthDay = [[], [], [], [], [], []]; // 生成一月对齐星期的天数,一周以周日开始 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 && this.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 && this.validDate(year, month, that.monthDay[4][index].date + 7) ) { that.monthDay[5].push({year, month, date: that.monthDay[4][index].date + 7}); } }) } } } 复制代码
css
<style scoped> .calendar-container { width: 100%; position: relative; color: #999; } .month-bg { position: absolute; top: 50%; left: 50%; /* color: #fcfcfc; */ color: #f6f6f6; font-size: 60px; transform: translate(-50%, -50%); z-index: -1; } .week-title { padding: 20upx 40upx; display: flex; justify-content: space-between; } .week-title>text { flex: 1; text-align: center; } .weekend { color: #F87D72; } .week-month { display: flex; justify-content: flex-start; padding: 20upx 40upx; color: #2b2b2b; } .week-month>.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; } .date-active::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; } .date-active>.price { color: #fff; } .date-active2::after { transform: translate(-50%, -68%); } </style> 复制代码
以上所述就是小编给大家介绍的《vue/uni-app之空手撕日历》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- vue日历组件
- 原生JavaScript实现造日历轮子
- 第二章 使用VUX建立日历
- uiw 1.4.0 发布,新增日历控件
- uiw 1.4.3 发布,增强日历控件
- Flutter日历,可以自定义风格UI
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。