微信小程序之实现常用日期格式-日历格式(二)

前言概述

本文介绍项目中常用到的日期格式--日历(总是显示一个月有效期选择),该实例分显示页面和日期组件页面两个页面:

实现过程

一、日期组件页面

1. 先实现页面效果,文件*.wxml和*.wxss代码如下:

1)需求只需要显示每个月自己的日期,由于该算法也显示了非自己月份的日期,所以需要过滤掉非当月的日期,在wxml使用wx:if="{ {item.year === lists.dateYear && item.month === lists.dateMonth}}";

2)item.isDisable ? 'opacity30' : (item.year === selectDay.year && item.month === selectDay.month && item.day === selectDay.day?'select':'')实现原理,判断是否有效期(isDisable ),非有效期增加'opacity30'实现透明度30%效果;而有效期判断是否被选中,选中则增加'select'实现高亮效果;

<view class="calendar">
	<!-- 日历头部 -->
	<view class="calendar-week">
		<view class="view">日</view>
		<view class="view">一</view>
		<view class="view">二</view>
		<view class="view">三</view>
		<view class="view">四</view>
		<view class="view">五</view>
		<view class="view">六</view>
	</view>
	<view wx:for="{
   
   {dateList}}" wx:for-item="lists" wx:key="dateList" class="day-box">
		<!-- 年月份信息 -->
		<view class="title">
			<view>{
   
   {lists.dateYear}}年{
   
   {lists.dateMonth>9?lists.dateMonth:"0"+lists.dateMonth}}月</view>
		</view>
		<!-- 日历主体 -->
		<view class="calendar-main">
			<view wx:for="{
   
   {lists.list}}" wx:key="index" class="day">
				<view wx:if="{
   
   {item.year === lists.dateYear && item.month === lists.dateMonth}}" class="day-item {
   
   {item.isDisable ? 'opacity30' : (item.year === selectDay.year && item.month === selectDay.month && item.day === selectDay.day?'select':'')}}" catchtap="selectChange" data-day="{
   
   {item.day}}" data-year="{
   
   {item.year}}" data-month="{
   
   {item.month}}" data-date-string="{
   
   {item.dateString}}" data-week-day="{
   
   {item.weekDay}}" data-isdisable="{
   
   {item.isDisable}}">
					<view class="text {
   
   {item.isWeekend ? 'orange' : (item.isToday ? 'blue' : '')}}">
						{
   
   {item.day}}
					</view>
					<view class="remark blue" wx:if="{
   
   {item.isToday}}">今天</view>
					<view class="remark orange" wx:if="{
   
   {item.isWeekend}}">休</view>
				</view>
			</view>
		</view>
	</view>
</view>
.calendar .title {
  font-weight: bold;
  text-align: center;
  padding: 20rpx 0 0;
}

.calendar .calendar-week {
  display: flex;
  line-height: 50rpx;
  height: 50rpx;
  color: #808080;
  background-color: #F3F6F8;
  padding: 0 25rpx;
}

.calendar .calendar-week .view {
  width: 100rpx;
  text-align: center;
}

.calendar .calendar-main {
  padding: 10rpx 25rpx 0;
  display: flex;
  flex-wrap: wrap;
}

.calendar .calendar-main .day {
  width: 100rpx;
  text-align: center;
  height: 100rpx;
  position: relative;
}

.calendar .calendar-main .day .day-item {
  height: 70rpx;
  padding-top: 30rpx;
}

.calendar .calendar-main .day .other-month {
  color: #ccc;
  display: none;
}

.calendar .calendar-main .day .remark {
  font-size: 20rpx;
}

.calendar .calendar-main .day .blue {
  color: #3D7AF5;
}

.calendar .calendar-main .day .orange {
  color: #FA7014;
}

.calendar .calendar-main .day .opacity30 {
  opacity: 0.3;
}

.calendar .calendar-main .day .select {
  background-color: #3D7AF5;
  border-radius: 8rpx;
}

.calendar .calendar-main .day .select .text {
  color: #fff;
}

.calendar .calendar-main .day .select .remark {
  color: #fff;
}

2. 接下来实现交互逻辑,文件*.js代码实现如下:

1)dateInit函数用于获取渲染的日历主体信息和所需要的data各种数据;

2)onLoad实现获取当天日期并渲染主体数据,加了判断是否选中过日期来变化高亮日期天数;

3)selectChange函数用于点击后把选中日期数据传回上一页,并跳转到上一页。

import util from '../../utils/util.js'
Page({
  /**
   * 页面的初始数据
   */
  data: {
    dateList: [], // 日历主体渲染数组
    nowDay: {}, // 今天日期
    selectDay: {}, // 选中时间
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    // 获取当前日期信息
    let now = new Date();
    let nowDay = {
      year: now.getFullYear(),
      month: now.getMonth() + 1,
      day: now.getDate()
    }
    let selectDay = nowDay;
    // 存在选择数据情况
    if (options.selectDay != 0) {
      selectDay = JSON.parse(options.selectDay);
    }
    this.setData({
      nowDay,
      selectDay
    });
    this.dateInit(nowDay.year, nowDay.month);
  },
  // 日历主体的渲染方法
  dateInit(setYear, setMonth) {
    let dateList = []; // 需要遍历的日历数组数据
    // 循环两个月数据(2)
    for (let i = 0; i < 2; i++) {
      let now = new Date(setYear, setMonth - 1 + i); // 当前月份的1号
      let startWeek = now.getDay(); // 目标月1号对应的星期
      let dayNum = new Date(setYear, setMonth + i, 0).getDate(); // 当前月有多少天
      let forNum = Math.ceil((startWeek + dayNum) / 7) * 7; // 当前月跨越的周数

      let dateObj = {};
      let list = [];
      for (let j = 0; j < forNum; j++) {
        const now2 = new Date(now);
        now2.setDate(j - startWeek + 1);

        let obj = {};
        let day = now2.getDate();
        let month = now2.getMonth() + 1;
        let year = now2.getFullYear();
        let weekDay = now2.getDay();
        let nowDay = this.data.nowDay;
        let isDisable;
        // 用于判断本月小于今天,下个月大于今天的日期不能选择
        if (month == nowDay.month) {
          isDisable = (day < nowDay.day) ? true : false;
        } else {
          isDisable = (day >= nowDay.day) ? true : false;
        }

        obj = {
          day,
          month,
          year,
          weekDay,
          dateString: util.formatTime(now2),
          isToday: (year === nowDay.year && month === nowDay.month && day === nowDay.day) ? true : false, // 是否今天
          isWeekend: (weekDay === 0 || weekDay === 6) ? true : false, // 是否周末
          isDisable
        };
        list[j] = obj;
      }
      dateObj = {
        dateYear: now.getFullYear(),
        dateMonth: now.getMonth() + 1,
        list: list
      }
      dateList.push(dateObj);
    }

    this.setData({
      dateList: dateList
    })
  },
  // 一天被点击时
  selectChange(e) {
    const weekDay = e.currentTarget.dataset.weekDay;
    const isDisable = e.currentTarget.dataset.isdisable;
    // 非有效期不能预约
    if (isDisable) {
      util.showToast('请选择有效期', 'none');
      return false;
    }
    // 周末不能预约
    if (weekDay === 0 || weekDay === 6) {
      util.showToast('请选择非休息日', 'none');
      return false;
    }
    // 获取星期几
    let weeks = util.getWeeks(weekDay);

    const year = e.currentTarget.dataset.year
    const month = e.currentTarget.dataset.month
    const day = e.currentTarget.dataset.day
    const dateString = e.currentTarget.dataset.dateString
    const selectDay = {
      year: year,
      month: month,
      day: day,
      dateString: dateString + ' ' + weeks
    }
    console.log(selectDay);
    this.setData({
      selectDay: selectDay
    });
    // 传数据到上一个页面
    let pages = getCurrentPages(); // 获取当前所有页面
    let prevPage = pages[pages.length - 2]; // 获取上一个页面并传参
    prevPage.setData({
      selectDay
    });
    wx.navigateBack({
      delta: 1, // 返回上一级页面
    })
  }
})

二、显示页面

1. 先实现页面效果,文件*.wxml和*.wxss代码如下:

<view class="time-box">
	<view class="time-title">预约日期</view>
	<view class="picker" bindtap="selectDate">
		<text>{
   
   {selectDay.dateString ? selectDay.dateString : dateString}}</text>
	</view>
</view>
.time-box {
  padding: 32rpx 30rpx;
  display: flex;
  background-color: #fff;
}

.time-box .time-title {
  color: #9A9A9A;
  margin-right: 73rpx;
  width: 200rpx;
}

.time-box .picker {
  width: 400rpx;
}

2. 接下来实现交互逻辑,文件*.js代码实现如下:

Page({
  /**
   * 页面的初始数据
   */
  data: {
    dateString: '2020-09-03 星期四'
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    
  },
  // 选择日期
  selectDate: function() {
    wx.navigateTo({
      url: '../calendarModule/calendarModule?selectDay=' + JSON.stringify(this.data.selectDay ? this.data.selectDay : 0)
    })
  }
})

 

Guess you like

Origin blog.csdn.net/king0964/article/details/108409311