实现功能
基本照抄ixc-page-calendar日历, 没有配置头部, 单一动画可自己扩展
注意返回的iconFont可以自己的
- vue文件
<template>
<div class="wrapper" :class="showPage ? 'show' : 'hide'">
<div class="header">
<div style="height: 100%; width: 80upx;" @click="back">
<text class="icon-font" style="color: white"></text>
</div>
<div class="middle">
<text class="title">选择日期</text>
</div>
</div>
<view>
<div class="calendar-weekday">
<text class="flex-item weekday-text"
:key="k"
:aria-label="`周${week}`"
v-for="(week,k) in ['日','一','二','三','四','五','六']">{{week}}</text>
</div>
<scroll-view class="calendar-list" scroll-y="true" :scroll-into-view="scrollIntoId">
<view v-for="(month,index) in monthsArray"
:key="index"
:id="sub+month.title"
:class="[!month.title && 'calendar-row']">
<text class="month-text"
v-if="month.title">{{month.title}}</text>
<view v-else
v-for="(cell,rowIndex) in month"
:key="`${index}-${rowIndex}`"
:ref="cell.ref"
:class="['row-item', cell.cellClass]"
:style="cell.isSelected ? selectedCellStyle:{}"
:accessible="true"
:aria-label="`${cell.text?cell.text:''},${cell.note?cell.note:''},${cell.ext?cell.ext:''}`"
@click="onClickDate(cell)">
<text :class="['calendar-note', cell.cls]"
:style="cell.isSelected ? selectedTextStyle:{}">{{cell.note}}</text>
<text :class="['calendar-day', cell.cls]"
:style="cell.isSelected ? selectedTextStyle:{}">{{cell.text}}</text>
<text :class="['calendar-ext', cell.cls]"
:style="cell.isSelected ? selectedTextStyle:{}">{{cell.ext}}</text>
</view>
</view>
</scroll-view>
</view>
</div>
</template>
<script>
import Format from './format.js'
export default {
components: {},
props: {
selectedDate: Array,
dateRange: {
type: Array,
required: true,
default: () => ([])
},
selectedNote: {
type: Array,
default: () => (['开始', '到达', '往返'])
},
isRange: {
type: Boolean,
default: false
},
needDestroy: {
type: Boolean,
default: false
},
descList: {
type: Array,
default: () => ([])
},
selectedCellStyle: {
type: Object,
default: () => ({})
},
selectedTextStyle: {
type: Object,
default: () => ({})
},
},
computed: {
today(){
return Format.getToDay()
},
monthsArray () {
const { dateRange: range, today, departDate, arriveDate, selectedNote, descList } = this;
const param = { range, today, departDate, arriveDate, selectedNote, descList }
return Format.generateDateCell(param);
}
},
data: () => ({
Format: Format,
showPage: false,
reSelect: true,
scrollIntoId: '',
departDate: '',
arriveDate: '',
sub: 'sub',
}),
created() {
},
mounted() {
},
methods: {
show(){
this.reSelect = true;
this.showPage = true;
this.detectShow();
},
back(){
this.reSelect = false;
this.showPage = false;
},
onClickDate (datConfig) {
const self = this;
if (datConfig.disabled || datConfig.isEmpty) return;
if (self.reSelect) {
self.departDate = '';
self.arriveDate = '';
self.reSelect = false;
}
if (self.isRange) {
if (self.departDate && Date.parse(self.departDate) <= Date.parse(datConfig.date)) {
self.arriveDate = datConfig.date;
} else {
self.departDate = datConfig.date;
}
if (self.departDate && self.arriveDate) {
self.dispatchDateChange([self.departDate, self.arriveDate]);
}
} else {
self.departDate = datConfig.date;
self.dispatchDateChange([self.departDate]);
}
},
dispatchDateChange (dateArr) {
const duration = 400;
setTimeout(() => {
this.back();
}, duration);
this.$emit('wxcPageCalendarDateSelected', {
date: dateArr
});
},
detectShow () {
if (this.isRange && this.selectedDate.length >= 2) {
this.departDate = this.selectedDate[0];
this.arriveDate = this.selectedDate[1];
} else if (this.selectedDate.length >= 1) {
this.departDate = this.selectedDate[0];
this.arriveDate = '';
}
for(var i = 0; i < this.monthsArray.length; i++){
var title = this.monthsArray[i].title
if(title){
var subtitle = this.sub+title
console.log('测试数据',title, this.departDate)
if(title == this.subId(this.departDate)){
this.scrollIntoId = this.sub + title
console.log('测试数据scrollIntoId',title, this.scrollIntoId)
}
}
}
},
subId(title){
return title.substring(0, 7)
},
}
};
</script>
<style >
@font-face {
font-family: 'iconfont';
src: url('~@/static/iconfont/iconfont.ttf');
}
.wrapper {
position: fixed;
z-index: 999999;
background: #ffffff;
height: 100%;
width: 100%;
top: 0px;
left: 0px;
}
.content {
height: 100%;
width: 100%;
background-color: #ffffff;
}
.show {
left: 0;
width: 100%;
transition: left .3s ease;
}
.hide {
left: 100%;
width: 100%;
transition: left .3s ease;
}
.header{
height: 83upx;
background-color: #00aafb;
display: flex;
flex-direction: row;
padding-top: 15upx;
padding-left: 15upx;
}
.icon-font{
font-family: 'iconfont';
font-size: 30upx;
}
.middle{
width: 100%;
display: flex;
padding-right: 95upx;
justify-content: center
}
.title{
font-size: 30upx;
color: white;
}
.calendar-weekday {
height: 60upx;
background-color: #ffffff;
border-bottom-width: 1upx;
border-top-width: 1upx;
border-color: #e2e2e2;
flex-direction: row;
display: flex;
border-bottom-style: solid;
justify-content: space-around;
align-items: center;
}
.flex-item {
flex: 1;
width: 20%;
text-align: center;
}
.weekday-text {
color: #000000;
flex: 1;
font-size: 24upx;
text-align: center;
}
.calendar-list {
position: absolute;
top: 143upx;
bottom: 0upx;
width: 100%;
}
.month-text {
font-size: 32upx;
height: 60upx;
line-height: 60upx;
width: 750upx;
display: flex;
text-align: center;
flex-direction: column;
align-items: center;
background-color: #f2f3f4;
}
.calendar-row {
height: 140upx;
display: flex;
flex-direction: row;
background-color: #ffffff;
border-bottom-width: 1px;
border-color: #f2f3f4;
border-bottom-style: solid;
align-items: center;
justify-content: space-between;
}
.row-item {
flex: 1;
height: 140upx;
padding-top: 10upx;
padding-bottom: 10upx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.calendar-note {
height: 36upx;
line-height: 36upx;
font-size: 24upx;
color: #000000;
text-align: center;
}
.calendar-day {
height: 48upx;
line-height: 48upx;
font-size: 36upx;
color: #000000;
text-align: center;
}
.calendar-ext {
height: 36upx;
line-height: 36upx;
color: #999999;
text-align: center;
font-size: 24upx;
text-overflow: ellipsis;
}
.calendar-holiday {
color: #FF5000;
}
.calendar-rest {
color: #FF5000;
}
.item-row-selected {
color: #ffffff;
background-color: #FFC900;
text-align: center;
}
.item-text-selected {
color: #3d3d3d;
text-align: center;
}
.calendar-disabled {
color: #CCCCCC;
}
.cell-disabled {
background-color: #FBFBFB;
}
.calendar-day-include {
background-color: #FFF7D6;
}
</style>
- Format.js文件
/**
* CopyRight (C) 2017-2022 Alibaba Group Holding Limited.
* Created by Tw93 on 2017/07/29.
*/
const Format = {
// 国际节日
GLOBAL_HOLIDAY: {
'01-01': '元旦',
'02-14': '情人',
'05-01': '劳动',
'06-01': '儿童',
'10-01': '国庆',
'12-25': '圣诞'
},
// 传统节日
TRADITIONAL_HOLIDAY: {
'除夕': ['2015-02-18', '2016-02-07', '2017-01-27', '2018-02-15', '2019-02-04', '2020-01-24'],
'春节': ['2015-02-19', '2016-02-08', '2017-01-28', '2018-02-16', '2019-02-05', '2020-01-25'],
'元宵': ['2015-03-05', '2016-02-22', '2017-02-11', '2018-03-02', '2019-02-19', '2020-02-08'],
'清明': ['2015-04-05', '2016-04-04', '2017-04-04', '2018-04-05', '2019-04-05', '2020-04-04'],
'端午': ['2015-06-20', '2016-06-09', '2017-05-30', '2018-06-18', '2019-06-07', '2020-06-25'],
'中秋': ['2015-09-27', '2016-09-15', '2017-10-04', '2018-09-24', '2019-09-13', '2020-10-01'],
'重阳': ['2015-10-21', '2016-10-09', '2017-10-28', '2018-10-17', '2019-10-07', '2020-10-25']
},
// 放假日
REST_DAYS: ['2017-10-01', '2017-10-02', '2017-10-03', '2017-10-04', '2017-10-05', '2017-10-06', '2017-10-07',
'2017-10-08'
],
// 工作日
WORK_DAYS: ['2017-09-30'],
_getTraditionalHoliday() {
const HOLIDAY_TEMP = {};
const keys = Object.keys(Format.TRADITIONAL_HOLIDAY);
keys.forEach((k) => {
const arr = Format.TRADITIONAL_HOLIDAY[k];
arr.forEach((i) => {
HOLIDAY_TEMP[i] = k;
})
});
return HOLIDAY_TEMP;
},
_isDate(obj) {
const type = obj === null ? String(obj) : {}.toString.call(obj) || 'object';
return type === '[object date]';
},
/**
* 检测Hash
*
* @method _checkHash
* @private
*/
_checkHash(url, hash) {
return url && url.match(/#/) && url.replace(/^.*#/, '') === hash;
},
/**
* 获取当前日期的毫秒数
* @method getTime
* @param {String} date
* @return {Number}
*/
getTime(date) {
if (Format._isDate(date)) {
return new Date(date).getTime();
} else {
try {
return new Date(date.replace(/-/g, '/')).getTime();
} catch (e) {
return 0;
}
}
},
_isInRange(range, date) {
const start = Format.getTime(range[0]);
const end = Format.getTime(range[1]);
const d = Format.getTime(date);
return (start <= d && end >= d);
},
_isInSelectRange(range, date) {
const start = Format.getTime(range[0]);
const end = Format.getTime(range[1]);
const d = Format.getTime(date);
return (start < d && end > d);
},
_fixNum(num) {
return (num < 10 ? '0' : '') + num;
},
/**
* 是否是周末
* @method isWeekend
* @param {String} date
* @return {Boolean}
*/
_isWeekend(date) {
const day = new Date(date.replace(/-/g, '/')).getDay();
return day === 0 || day === 6;
},
/**
* 是否是今天
* @method isToday
* @param {String} date
* @return {Boolean}
*/
_isToday(today, date) {
return Format.getTime(today) === Format.getTime(date);
},
/**
* 检查是否是闰年
* @method _checkLeapYear
* @param {Number} y 年份
* @param {Date} t today
* @protected
*/
_getMonthDays(y, t) {
const MONTH_DAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
const year = y || t.getFullYear();
let isLeapYear = false;
if (year % 100) {
isLeapYear = !(year % 4);
} else {
isLeapYear = !(year % 400);
}
if (isLeapYear) {
MONTH_DAYS[1] = 29;
} else {
MONTH_DAYS[1] = 28;
}
return MONTH_DAYS;
},
/**
* 当月1号前面有多少空格
* @method _getPadding
* @protected
*/
_getPadding(year, month) {
const date = new Date(year + '/' + month + '/1');
return date.getDay();
},
_unique(array) {
return Array.prototype.filter.call(array, function(item, index) {
return array.indexOf(item) === index;
});
},
getToDay() {
return new Date().getFullYear() + '-' + Format._fixNum(new Date().getMonth() + 1) + '-' + Format._fixNum(new Date().getDate());
},
getWeekRows(y, m, today, dateRange, departDate, arriveDate, selectedNote, descList) {
const monthDays = Format._getMonthDays(y, today);
const padding = Format._getPadding(y, m, 7);
const num = monthDays[m - 1] + padding;
const rows = Math.ceil(num / 7);
const remain = num % 7;
const rowsData = [];
for (let i = 1; i <= rows; i++) {
const cells = [];
for (let j = 1; j <= 7; j++) {
let cell = {};
// 前后空格
if (i === 1 && j <= padding || remain && i === rows && j > remain) {
cell.isEmpty = true;
} else {
const d = (i - 1) * 7 + j - padding;
const date = y + '-' + Format._fixNum(m) + '-' + Format._fixNum(d);
let cls = [];
let ref = '';
const cellClass = [];
const isInRange = Format._isInRange(dateRange, date);
let disabled = false;
const global = Format._fixNum(m) + '-' + Format._fixNum(d);
let note = '';
let ext = '';
let isSelected = false;
if (descList && descList.length > 0) {
const nowDesc = descList.filter(item => item.date === date);
if (nowDesc && nowDesc.length > 0) {
ext = nowDesc[0].value;
if (nowDesc[0].emphasize) {
cls.push('calendar-holiday');
}
}
}
// 国际节日
if (Format.GLOBAL_HOLIDAY[global]) {
note = Format.GLOBAL_HOLIDAY[global];
cls.push('calendar-holiday');
}
const tHoliday = Format._getTraditionalHoliday()[date];
// 传统节日
if (tHoliday) {
note = tHoliday;
cls.push('calendar-holiday');
}
// 放假日
if (Format.REST_DAYS.indexOf(date) > -1) {
cls.push('calendar-holiday');
}
// 工作日
if (Format.WORK_DAYS.indexOf(date) > -1) {
cls.push('calendar-work');
}
// 周末
if (Format._isWeekend(date)) {
cls.push('calendar-holiday');
}
// 今天
if (Format._isToday(today, date)) {
cls.push('calendar-today');
note = '今天';
}
// 不在日期范围内
if (!isInRange) {
disabled = true;
}
if (disabled) {
cls = [];
cls.push('calendar-disabled');
cellClass.push('cell-disabled');
}
if (!ext && disabled && isInRange) {
ext = '不可选';
}
if (departDate === date || arriveDate === date) {
note = departDate === date ? selectedNote[0] : selectedNote[1];
ref = departDate === date ? 'departDate' : 'arriveDate';
if (departDate === arriveDate && selectedNote.length >= 3) {
note = selectedNote[2];
}
isSelected = true;
cls.push('item-text-selected');
cellClass.push('item-row-selected');
}
if (departDate && arriveDate && Format._isInSelectRange([departDate, arriveDate], date)) {
cellClass.push('calendar-day-include');
}
cell = {
isSelected,
isEmpty: false,
ref,
cls: Format._unique(cls).join(' '),
cellClass: Format._unique(cellClass).join(' '),
note: note,
date: date,
ext: ext,
disabled: disabled,
text: d
};
}
cells.push(cell);
}
rowsData.push(cells);
}
return rowsData;
},
generateDateCell({
range,
today,
departDate,
arriveDate,
selectedNote,
descList
}) {
const start = new Date(range[0].replace(/-/g, '/'));
const end = new Date(range[1].replace(/-/g, '/'));
const startYear = start.getFullYear();
const startMonth = start.getMonth() + 1;
const endYear = end.getFullYear();
const endMonth = end.getMonth() + 1;
const l = (endYear - startYear) * 12 + endMonth - startMonth + 1;
let y = startYear;
let n = startMonth;
const months = [];
for (let i = 0; i < l; i++) {
if (n > 12) {
n = 1;
y++;
}
months.push({
title: `${y}-${Format._fixNum(n)}`
},
...Format.getWeekRows(y, n, today, range, departDate, arriveDate, selectedNote, descList)
);
n++;
}
return months
},
}
export default Format
网友评论