美團市值突飛猛進,確實霸佔了我們的喫喝玩樂,所以想做什麼東西,研究一下美團也是不錯的。最近需要用到一個酒店入住日期選擇的組件,看了一下美團的設計,很好用,在此實現一下。
效果圖如下:
體驗路徑(並獲取源碼):
代碼邏輯:
var Moment = require("../../utils/moment.js");
var DATE_LIST = [];
var DATE_YEAR = new Date().getFullYear();
var DATE_MONTH = new Date().getMonth() + 1;
var DATE_DAY = new Date().getDate();
Page({
data: {
maxMonth: 7, //最多渲染月數
dateList: [],
systemInfo: {},
weekStr: ['日', '一', '二', '三', '四', '五', '六'],
checkInDate: Moment(new Date()).format('YYYY-MM-DD'),
checkOutDate: Moment(new Date()).add(1, 'day').format('YYYY-MM-DD'),
markcheckInDate: false, //標記開始時間是否已經選擇
markcheckOutDate: false, //標記結束時間是否已經選擇
sFtv: [
{
month:1,
day:1,
name:"元旦"
},
{
month: 2,
day: 14,
name: "情人節"
},
{
month: 3,
day: 8,
name: "婦女節"
},
{
month: 3,
day: 12,
name: "植樹節"
},
{
month: 3,
day: 15,
name: "消費者權益日"
},
{
month: 4,
day: 1,
name: "愚人節"
},
{
month: 5,
day: 1,
name: "勞動節"
},
{
month: 5,
day: 4,
name: "青年節"
},
{
month: 5,
day: 12,
name: "護士節"
},
{
month: 6,
day: 1,
name: "兒童節"
},
{
month: 7,
day: 1,
name: "建黨節"
},
{
month: 8,
day: 1,
name: "建軍節"
},
{
month: 9,
day: 10,
name: "教師節"
},
{
month: 9,
day: 28,
name: "孔子誕辰"
},
{
month: 10,
day: 1,
name: "國慶節"
},
{
month: 10,
day: 6,
name: "老人節"
},
{
month: 10,
day: 24,
name: "聯合國日"
},
{
month: 12,
day: 24,
name: "平安夜"
},
{
month: 12,
day: 25,
name: "聖誕節"
}
]
},
onLoad: function (options) {
// 頁面初始化 options爲頁面跳轉所帶來的參數
this.createDateListData();
var _this = this;
// 頁面初始化 options爲頁面跳轉所帶來的參數
var checkInDate = options.checkInDate ? options.checkInDate : Moment(new Date()).format('YYYY-MM-DD');
var checkOutDate = options.checkOutDate ? options.checkOutDate : Moment(new Date()).add(1, 'day').format('YYYY-MM-DD');
wx.getSystemInfo({
success: function (res) {
_this.setData({ systemInfo: res, checkInDate: checkInDate, checkOutDate: checkOutDate });
}
})
},
onReady: function () {
// 頁面渲染完成
},
onShow: function () {
this.selectDataMarkLine()
},
onHide: function () {
// 頁面隱藏
},
onUnload: function () {
// 頁面關閉
},
//選擇的入住與離店時間段
selectDataMarkLine: function () {
let dateList = this.data.dateList;
let { checkInDate, checkOutDate } = wx.getStorageSync("ROOM_SOURCE_DATE");
let curreInid = checkInDate.substr(0, 4) + "-" + (checkInDate.substr(5, 2) < 10 ? checkInDate.substr(6, 1) : checkInDate.substr(5, 2));//選擇入住的id
let curreOutid = checkOutDate.substr(0, 4) + "-" + (checkOutDate.substr(5, 2) < 10 ? checkOutDate.substr(6, 1) : checkOutDate.substr(5, 2));//選擇離店的id
let dayIn = checkInDate.substr(8, 2) >= 10 ? checkInDate.substr(8, 2) : checkInDate.substr(9, 1);//選擇入住的天id
let dayOut = checkOutDate.substr(8, 2) >= 10 ? checkOutDate.substr(8, 2) : checkOutDate.substr(9, 1);//選擇離店的天id
let monthIn = checkInDate.substr(5, 2) >= 10 ? checkInDate.substr(5, 2) : checkInDate.substr(6, 1);//選擇入店的月id
let monthOut = checkOutDate.substr(5, 2) >= 10 ? checkOutDate.substr(5, 2) : checkOutDate.substr(6, 1);//選擇離店的月id
if (curreInid == curreOutid) {//入住與離店是當月的情況
for (let i = 0; i < dateList.length; i++) {
if (dateList[i].id == curreInid) {
let days = dateList[i].days;
for (let k = 0; k < days.length; k++) {
if (days[k].day >= dayIn && days[k].day <= dayOut) {
days[k].class = days[k].class + ' bgitem';
}
if (days[k].day == dayIn) {
days[k].class = days[k].class + ' active';
days[k].inday = true;
}
if (days[k].day == dayOut) {
days[k].class = days[k].class + ' active';
days[k].outday = true;
}
}
}
}
} else {//跨月
for (let j = 0; j < dateList.length; j++) {
if (dateList[j].month == monthIn) {//入住的開始月份
let days = dateList[j].days;
for (let k = 0; k < days.length; k++) {
if (days[k].day >= dayIn) {
days[k].class = days[k].class + ' bgitem';
}
if (days[k].day == dayIn) {
days[k].class = days[k].class + ' active';
days[k].inday = true;
}
}
} else {//入住跨月月份
if (dateList[j].month < monthOut && dateList[j].month > monthIn) {//離店中間的月份
let days = dateList[j].days;
for (let k = 0; k < days.length; k++) {
days[k].class = days[k].class + ' bgitem';
}
} else if (dateList[j].month == monthOut) {//離店最後的月份
let days = dateList[j].days;
for (let k = 0; k < days.length; k++) {
if (days[k].day <= dayOut) {
days[k].class = days[k].class + ' bgitem';
}
if (days[k].day == dayOut) {
days[k].class = days[k].class + ' active';
days[k].outday = true;
}
}
}
}
}
}
this.setData({
dateList: dateList
})
},
createDateListData: function () {
var dateList = [];
var now = new Date();
/*
設置日期爲 年-月-01,否則可能會出現跨月的問題
比如:2017-01-31爲now ,月份直接+1(now.setMonth(now.getMonth()+1)),則會直接跳到跳到2017-03-03月份.
原因是由於2月份沒有31號,順推下去變成了了03-03
*/
now = new Date(now.getFullYear(), now.getMonth(), 1);
for (var i = 0; i < this.data.maxMonth; i++) {
var momentDate = Moment(now).add(this.data.maxMonth - (this.data.maxMonth - i), 'month').date;
var year = momentDate.getFullYear();
var month = momentDate.getMonth() + 1;
var days = [];
var totalDay = this.getTotalDayByMonth(year, month);
var week = this.getWeek(year, month, 1);
//-week是爲了使當月第一天的日期可以正確的顯示到對應的周幾位置上,比如星期三(week = 2),
//則當月的1號是從列的第三個位置開始渲染的,前面會佔用-2,-1,0的位置,從1開正常渲染
for (var j = -week + 1; j <= totalDay; j++) {
var tempWeek = -1;
if (j > 0)
tempWeek = this.getWeek(year, month, j);
var clazz = '';
if (tempWeek == 0 || tempWeek == 6)
clazz = 'week'
if (j < DATE_DAY && year == DATE_YEAR && month == DATE_MONTH)
//當天之前的日期不可用
clazz = 'unavailable ' + clazz;
else
clazz = '' + clazz
days.push({ day: j, class: clazz })
}
var dateItem = {
id: year + '-' + month,
year: year,
month: month,
days: days
}
dateList.push(dateItem);
}
var sFtv = this.data.sFtv;
for (let i = 0; i < dateList.length; i++){//加入公曆節日
for(let k = 0; k < sFtv.length; k++){
if (dateList[i].month == sFtv[k].month){
let days = dateList[i].days;
for (let j = 0; j < days.length; j++){
if (days[j].day == sFtv[k].day){
days[j].daytext = sFtv[k].name
}
}
}
}
}
this.setData({
dateList: dateList
});
DATE_LIST = dateList;
},
/*
* 獲取月的總天數
*/
getTotalDayByMonth: function (year, month) {
month = parseInt(month, 10);
var d = new Date(year, month, 0);
return d.getDate();
},
/*
* 獲取月的第一天是星期幾
*/
getWeek: function (year, month, day) {
var d = new Date(year, month - 1, day);
return d.getDay();
},
/**
* 點擊日期事件
*/
onPressDate: function (e) {
var { year, month, day } = e.currentTarget.dataset;
//當前選擇的日期爲同一個月並小於今天,或者點擊了空白處(即day<0),不執行
if ((day < DATE_DAY && month == DATE_MONTH) || day <= 0) return;
var tempMonth = month;
var tempDay = day;
if (month < 10) tempMonth = '0' + month
if (day < 10) tempDay = '0' + day
var date = year + '-' + tempMonth + '-' + tempDay;
//如果點擊選擇的日期A小於入住時間,則重新渲染入住時間爲A
if ((this.data.markcheckInDate && Moment(date).before(this.data.checkInDate) || this.data.checkInDate === date)) {
this.setData({
markcheckInDate: false,
markcheckOutDate: false,
dateList: DATE_LIST.concat()
});
};
if (!this.data.markcheckInDate) {
this.setData({
checkInDate: date,
markcheckInDate: true,
dateList: DATE_LIST.concat()
});
} else if (!this.data.markcheckOutDate) {
this.setData({
checkOutDate: date,
markcheckOutDate: true,
});
//設緩存,返回頁面時,可在onShow時獲取緩存起來的日期
wx.setStorage({
key: 'ROOM_SOURCE_DATE',
data: {
checkInDate: this.data.checkInDate,
checkOutDate: this.data.checkOutDate
}
});
wx.navigateBack({
delta: 1, // 回退前 delta(默認爲1) 頁面
});
}
this.renderPressStyle(year, month, day);
},
renderPressStyle: function (year, month, day) {
this.createDateListData();//重新點擊時數據初始化
var dateList = this.data.dateList;
//渲染點擊樣式
for (var i = 0; i < dateList.length; i++) {
var dateItem = dateList[i];
var id = dateItem.id;
if (id === year + '-' + month) {
var days = dateItem.days;
for (var j = 0; j < days.length; j++) {
var tempDay = days[j].day;
if (tempDay == day) {
days[j].class = days[j].class + ' active';
days[j].inday = true;
break;
}
}
break;
}
}
this.setData({
dateList: dateList
});
}
})