微信小程序之实现常用日期格式-月历滑动格式(三)

前言概述

        本文介绍项目中常用到的日期格式--月历滑动格式,顶部显示当前月的月历,默认选择当天的日期,且能滑动月历选择需要的日期:

实现过程

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

        1)滑动功能使用组件scroll-view,样式实现参考下面代码;为了实现加载时默认选择当天的日期,可使用组件属性scroll-into-view,属性值“toView”需用setData设置,不然不起作用;

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

<view class="container">
	<view class="tabs-box">
		<scroll-view class="time-tabs" scroll-x scroll-into-view="{
   
   {toView}}" scroll-with-animation>
			<view wx:for="{
   
   {list}}" wx:key="index" class="day {
   
   {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}}" id="{
   
   {item.id}}">
				<view class="month">{
   
   {item.year}}-{
   
   {item.month}}</view>
				<view class="text {
   
   {item.isWeekend ? 'orange' : ''}}">
					{
   
   {item.day}}
				</view>
				<view class="week">{
   
   {item.week}}</view>
			</view>
		</scroll-view>
		<view class="remark"><text>滑动选择更多日期</text></view>
	</view>
	<view class="timeList">
		<view class="table">
			<view class="tr title">
				<view class="th first">时间段</view>
				<view class="th center">剩余数</view>
				<view class="th last">操作</view>
			</view>
			<scroll-view scroll-y="true" style="height: {
   
   {clientHeight?clientHeight-tabsBoxHeight-titleHeight+'px':'auto'}}">
				<view class="tr septalLine" wx:for="{
   
   {timeList}}" wx:key="id">
					<view class="td first">{
   
   {item.time}}</view>
					<view class="td center">{
   
   {item.bookingNumber}}</view>
					<view class="td last">预约</view>
				</view>
			</scroll-view>
		</view>
	</view>
</view>
/* 日期选择 */
.tabs-box {
  height: 228rpx;
}
.time-tabs {
  white-space: nowrap;
}

.time-tabs .day {
  display: inline-block;
  width: 150rpx;
  height: 170rpx;
  text-align: center;
  position: relative;
  font-size: 26rpx;
  border: 2rpx solid #E6E6E6;
}

.time-tabs .day.opacity30 {
  opacity: 0.3;
}

.time-tabs .day .month {
  color: #E6E6E6;
  padding: 10rpx 0 14rpx;
}

.time-tabs .day .text {
  font-size: 32rpx;
  color: #343434;
  font-weight: bold;
}

.time-tabs .day .week {
  color: #999;
  background-color: #F0F3F5;
  position: absolute;
  bottom: 0;
  width: 100%;
  text-align: center;
  padding: 8rpx 0;
}

.time-tabs .day .orange {
  color: #FA7014;
}

.time-tabs .day.select {
  border-color: #3E7AF5;
}

.time-tabs .day.select .month, .time-tabs .day.select .text {
  color: #3E7AF5;
}

.time-tabs .day.select .week {
  color: #fff;
  background-color: #3E7AF5;
}

.remark {
  color: #9A9A9A;
  font-size: 26rpx;
  text-align: center;
  margin-top: 20rpx;
}

.remark image {
  width: 32rpx;
  height: 14rpx;
  vertical-align: middle;
  margin-top: -6rpx;
}

.remark text {
  margin: 0 6rpx
}

/* 预约时间列表 */
.table {
  padding: 0 30rpx;
}

.table .tr {
  display: flex;
  padding: 40rpx 0 30rpx;
}

.table .tr .th {
  color: #666;
  margin-bottom: 10rpx;
}

.table .tr .th, .table .tr .td {
  text-align: center;
}

.table .tr .td {
  font-size: 32rpx;
  color: #343434;
}

.table .tr .first {
  width: 188rpx;
}

.table .tr .center {
  flex: 1;
}

.table .tr .last {
  width: 120rpx;
}

.table .tr .td.last {
  height: 60rpx;
  line-height: 60rpx;
  border: 2rpx solid #3E7AF5;
  color: #3E7AF5;
  border-radius: 8rpx;
  font-size: 28rpx;
  margin-top: -12rpx;
}

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

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

        2)onLoad实现获取当天日期并渲染主体数据,加了判断是否选中过日期来变化高亮日期天数;并计算日期列表的高度,实现只滚动日期列表,不影响滑动切换日期和查看标题;

        3)selectChange函数用于点击后把选中日期数据,如果要实现选中不同日期显示不同的日期列表,可在这里增加传参数调接口获取数据后替换timeList的数据。

import util from '../../utils/util.js'
Page({
  /**
   * 页面的初始数据
   */
  data: {
    tabsBoxHeight: 0, // 时间选择高度
    titleHeight: 0, // 时间列表高度
    clientHeight: 0, //可视区域高度
    nowDay: {}, // 今天日期
    selectDay: {}, // 选中时间
    list: [],
    toView: 't1', // 用于定位滚动位置
    timeList: [{
      id: 1,
      time: '08:30-09:00',
      bookingNumber: 4
    }, {
      id: 2,
      time: '09:00-09:30',
      bookingNumber: 10
    }, {
      id: 3,
      time: '09:00-09:30',
      bookingNumber: 10
    }, {
      id: 4,
      time: '09:00-09:30',
      bookingNumber: 10
    }, {
      id: 5,
      time: '09:00-09:30',
      bookingNumber: 10
    }, {
      id: 6,
      time: '09:00-09:30',
      bookingNumber: 10
    }, {
      id: 7,
      time: '09:00-09:30',
      bookingNumber: 10
    }]
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    // 计算时间高度
    let that = this;
    this.nodeHeight('.tabs-box', 'tabsBoxHeight');
    this.nodeHeight('.tr.title', 'titleHeight');
    console.log(this.data)
    wx.getSystemInfo({
      success: function (res) {
        console.log(res.windowHeight)
        that.setData({
          // 可视区域高度
          clientHeight: res.windowHeight
        });
      }
    });

    // 获取当前日期信息
    let now = new Date();
    let month = now.getMonth() + 1;
    month = month >= 10 ? month : '0' + month;
    let day = now.getDate();
    day = day >= 10 ? day : '0' + day;
    let nowDay = {
      year: now.getFullYear(),
      month,
      day
    }
    let selectDay = nowDay;
    this.setData({
      nowDay,
      selectDay
    });
    this.dateInit(nowDay.year, nowDay.month);
  },
  // 日历主体的渲染方法
  dateInit(setYear, setMonth) {
    // 循环月数据
    let now = new Date(setYear, setMonth - 1); // 当前月份的1号
    let dayNum = new Date(setYear, setMonth, 0).getDate(); // 当前月有多少天

    let list = [];
    let toView;
    for (let j = 0; j < dayNum; j++) {
      const now2 = new Date(now);
      now2.setDate(j + 1);

      let obj = {};
      let day = now2.getDate();
      day = day >= 10 ? day : '0' + day; // 补0

      let month = now2.getMonth() + 1;
      month = month >= 10 ? month : '0' + month; // 补0

      let year = now2.getFullYear();
      let weekDay = now2.getDay();
      let week = util.getWeeks(weekDay);
      let nowDay = this.data.nowDay;
      let isDisable;
      // 用于判断本月小于今天,下个月大于今天的日期不能选择
      if (month == nowDay.month) {
        isDisable = (day < nowDay.day) ? true : false;
      } else {
        isDisable = (day >= nowDay.day) ? true : false;
      }
      // 获取今天的id前两个数字     
      if (day == nowDay.day) {
        toView = 't' + (j - 2);
      }

      obj = {
        id: 't' + j,
        day,
        month,
        year,
        weekDay,
        week,
        dateString: util.formatTime(now2),
        isWeekend: (weekDay === 0 || weekDay === 6) ? true : false, // 是否周末
        isDisable
      };
      list[j] = obj;
    }
    this.setData({
      list,
      toView // 赋值需定位的位置
    })
  },
  // 一天被点击时
  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
    }
    this.setData({
      selectDay: selectDay
    });
  },
  // 获取节点高度
  nodeHeight(nodeName, nodeHeight) {
    let that = this;
    var query = wx.createSelectorQuery();
    query.select(nodeName).boundingClientRect();
    query.exec(function (res) {
      switch (nodeHeight) {
        case 'tabsBoxHeight':
          that.setData({
            tabsBoxHeight: res[0].height
          });
          break;
        case 'titleHeight':
          that.setData({
            titleHeight: res[0].height
          });
          break;
      }
    });
  }
})

Guess you like

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