• [组件封装] 微信小程序


    描述

    切换月份, 当天文案为今天, 日期背景变色, 日期红点标识, 点击选中日期.

    效果

    源码

    calendar.wxml

    <view class="component">
      <view class="header">
        <view bindtap="handlePrevMonthClick">{{'<'}}</view>
        <view>{{year}}年{{month}}月</view>
        <view bindtap="handleNextMonthClick">></view>
      </view>
      <view>
        <view class="week">周一</view>
        <view class="week">周二</view>
        <view class="week">周三</view>
        <view class="week">周四</view>
        <view class="week">周五</view>
        <view class="week">周六</view>
        <view class="week">周日</view>
      </view>
      <view class="daybox">
        <block wx:for="{{dayList}}" wx:key="{{index}}">
          <view wx:if="{{item.day}}" class="day {{item.day === day ? 'day-checked': ''}} {{item.bg ? 'day-bg' : ''}}" data-day="{{item.day}}" bindtap="handleDayClick">
            <view>{{item.isToday ? '今天' : item.day}}</view>
            <view class="point" wx:if="{{item.point}}"></view>
          </view>
          <view wx:else class="day"></view>
        </block>
      </view>
    </view>
    

    calendar.js

    const weekNameMap = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
    
    Component({
      properties: {
        mydate: String,  // 选中的天  Date String 格式
        mylist: Array,
      },
    
      data: {
        year: null,
        month: null,
        day: null,
        list: [],
      },
    
      lifetimes: {
        attached: function () {
          const now = new Date();
          this.setData({
            year: now.getFullYear(),
            month: now.getMonth() + 1,
            day: now.getDate(),
          }, this.calcDayList)
        },
      },
    
      observers: {
        'mydate': function (mydate) {
          let date = new Date(mydate);
          this.setData({
            year: date.getFullYear(),
            month: date.getMonth() + 1,
            day: date.getDate(),
          }, this.calcDayList);
        },
    
        'mylist': function (mylist) {
          this.setData({ list: mylist }, this.calcDayList);
        },
      },
    
      methods: {
    
        // 获取当月共多少天
        getThisMonthDays: function (year, month) {
          return new Date(year, month, 0).getDate()
        },
    
        // 获取当月第一天星期几   0 星期日
        getFirstDayOfWeek: function (year, month) {
          return new Date(Date.UTC(year, month - 1, 1)).getDay();
        },
    
    
        calcDayList: function () {
          const { year, month, list, } = this.data;
    
          let totalDay = this.getThisMonthDays(year, month);
          let firstDay = this.getFirstDayOfWeek(year, month);
    
          let dayList = [];
          for (let i = 0; i < (totalDay); i++) {
            dayList.push({
              day: i + 1,
              weekName: weekNameMap[(firstDay + i) % 7],
            })
          }
    
          // 向前添加
          for (let i = 0; i < (firstDay || 7) - 1; i++) {
            dayList.unshift({ day: 0, });
          }
    
          // 向后添加
          for (let i = 0; i < 42 - totalDay - ((firstDay || 7) - 1); i++) {
            dayList.push({ day: 0, });
          }
    
          // 当天
          let now = new Date();
          if (now.getFullYear() === year && now.getMonth() + 1 === month) {
            (dayList.find(d => d.day === now.getDate()) || {}).isToday = true;
          }
    
          // 业务数据处理
          list.forEach(item => {
            let find = dayList.find(d => d.day === item.day);
            if (find) {
              Object.assign(find, item);
            }
          })
    
          this.setData({ dayList, });
        },
    
        // 点击上个月
        handlePrevMonthClick: function () {
          let year = this.data.year;
          let month = this.data.month;
          if (this.data.month === 1) {
            year = this.data.year - 1;
            month = 12;
          } else {
            month = this.data.month - 1;
          }
          this.handleDateChange({ year, month });
        },
    
        // 点击下个月
        handleNextMonthClick: function () {
          let year = this.data.year;
          let month = this.data.month;
          if (this.data.month === 12) {
            year = this.data.year + 1;
            month = 1;
          } else {
            month = this.data.month + 1;
          }
          this.handleDateChange({ year, month });
        },
    
        // 点击 天
        handleDayClick: function (e) {
          const { day } = e.currentTarget.dataset;
          this.handleDateChange({ day })
        },
    
        // 处理日期变化
        handleDateChange: function (time) {
          const { year, month, day } = this.data;
          let date = { year, month, day, ...time };
          if (!this.data.mydate) {
            this.setData({ ...date });
            if (time.year || time.month) this.calcDayList();
          }
          this.triggerEvent('mydatechange', { date: new Date(`${date.year}/${date.month}/${date.day}`).toString() })
        }
    
    
    
      }
    })
    
    

    calendar.wxss

    .component {
      background: #fff;
    }
    .header {
      display: flex;
      justify-content: space-around;
      padding: 20rpx;
      border-top: 1px solid #eee;
    }
    .header view {
      height: 80rpx;
      line-height: 80rpx;
      font-size: 40rpx;
      color: rgba(0, 0, 0, 0.85);
      min- 100rpx;
    }
    .header view:nth-child(2n-1) {
      font-size: 50rpx;
    }
    
    .week {
      display: inline-block;
       107rpx;
      line-height: 2;
      color: rgba(0, 0, 0, 0.45);
      font-size: 28rpx;
      text-align: center;
    }
    
    .daybox {
      display: flex;
      flex-wrap: wrap;
      border-bottom: 1px solid #eee;
    }
    
    .day {
       107rpx;
      height: 107rpx;
      box-sizing: border-box;
      text-align: center;
      line-height: 2;
      color: rgba(0, 0, 0, 0.85);
      border: 4rpx solid #fff;
    }
    
    .day:nth-child(7n), .day:nth-child(7n-1) {
      color: #ff9b80;
    }
    
    .day-checked {
      border: 4rpx solid #ffa78f!important;
      border-radius: 10rpx;
    }
    .day-bg {
      background: #ffe9e4!important;
    }
    
    .point {
       10rpx;
      height: 10rpx;
      border-radius: 50%;
      background: #ff876d;
      margin: 0 auto;
      margin-top: 5rpx;
    }
    
    

    calendar.json

    {
      "component": true,
      "usingComponents": {}
    }
    

    使用例子

    参数 类型 默认值 说明
    mydate? String 当天时间字符串 选中的日期
    mylist? Array [] 当月数据
    handleDateClick? ({ detail: { date } }) => void 点击某天的的回调

    test.wxml

    <calendar mydate="{{mydate}}" mylist="{{list}}" bindmydatechange="handleDateClick" />
    

    test.js

    Page({  
      data: {
        mydate: new Date().toString(),
        mylist: [
          { day: 1,       // 当月天
            bg: true,     // 是否显示背景
            point: true,  // 是否显示圆点
          },
          { day: 3, bg: true },
          { day: 4, bg: true },
          { day: 5, bg: true, point: true },
          { day: 6, bg: true, point: true },
          { day: 7, point: true },
          { day: 8, point: true },
          { day: 9, point: true },
        ]
      },
    
      handleDateClick: function ({ detail: { date } }) {
        this.setData({ mydate: date });
      },
    
    })
    

    test.json

    {
      "navigationBarTitleText": "demo",
      "usingComponents": {
        "calendar": "/components/calendar/calendar"
      }
    }
    

    注意

    组件properties的数据类型不支持Date, 所以日期使用字符串格式传递。


  • 相关阅读:
    让 awesome , emacs , fcitx 一起工作(为awesome添加环境变量,和开机运行脚本)
    告别windows
    使用 Emacs PO mode 编辑 django PO 文件
    [转] Awesome autostart. [为awesome 设置环境变量]
    让 awesome 支持双屏
    解决长email在表格td中不自动换行的问题 & CSS强制不换行
    使用pdb (ipdb) 调试 python 程序
    ClickOnce 部署概述
    SQL Server 2005 CE基础概要
    运算符优先级 (TransactSQL)
  • 原文地址:https://www.cnblogs.com/whosmeya/p/12557443.html
Copyright © 2020-2023  润新知