微信小程序--创建一个日历组件

微信小程序–创建一个日历组件

  • 可以创建一个日历组件,来展示当前月份的日期,并支持切换月份的功能。
一、目录结构
/pages
  /calendar
    calendar.wxml
    calendar.scss
    calendar.js
    calendar.json

二、calendar.wxml
  <view class="calendar">
    <view class="header">
      <view bindtap="changeMonth" data-direction="prev">
        <van-icon name="arrow-left" />
      </view>
      <text>{{year}}年{{month}}月</text>
      <van-icon name="arrow" bindtap="changeMonth" data-direction="next" />
    </view>
    <view class="days">
      <view class="week">
        <text></text>
        <text></text>
        <text></text>
        <text></text>
        <text></text>
        <text></text>
        <text></text>
      </view>
      <view class="dates">
        <block wx:for="{{days}}" wx:key="index">
          <view class="date">{{item}}</view>
        </block>
      </view>
    </view>
  </view>
三、calendar.scss
.calendar {
  width: 100%;
  border-radius: 15rpx;
  background-color: #fff;
  padding: 20rpx;
}

.header {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size:32rpx;
}

.days {
  margin-top: 20px;
}

.week {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 5px;
  text-align: center;
  margin-bottom: 20px;
}

.dates {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 10px 5px;
}

.date {
  width: 100%;
  height: 60px;
  text-align: center;
  padding: 10px;
  background-color: #f0f0f0;
  color: #000;
}
四、calendar.js
Page({
  data: {
    year: new Date().getFullYear(),
    month: new Date().getMonth() + 1,
    days: [],
  },
  
  onLoad() {
    this.loadCalendar();
  },

  loadCalendar() {
    const { year, month } = this.data;
    // 获取当月的第一天是星期几
    const firstDay = new Date(year, month - 1, 1).getDay();
    // 获取当月的天数
    const totalDays = new Date(year, month, 0).getDate();
    // 创建日期数组
    const days = [];
    // 填充空白日期
    for (let i = 0; i < firstDay; i++) {
      days.push('');
    }
    // 填充实际日期
    for (let i = 1; i <= totalDays; i++) {
      days.push(i);
    }
    
    this.setData({ days });
  },

  changeMonth(event) {
    const direction = event.currentTarget.dataset.direction;
    let { year, month } = this.data;
    
    if (direction === 'prev') {
      month--;
      if (month < 1) {
        month = 12;
        year--;
      }
    } else if (direction === 'next') {
      month++;
      if (month > 12) {
        month = 1;
        year++;
      }
    }
    
    this.setData({ year, month }, () => {
      this.loadCalendar();
    });
  }
});
五、效果图(样式可以按需更改)

在这里插入图片描述
在这里插入图片描述

六、padStart

padStart(2, '0') 是 JavaScript 字符串的方法,用于填充字符串的开头直到指定的长度。

使用了 padStart(2, '0') 来确保日期和月份都是两位数格式。

str.padStart(targetLength, padString);
  • targetLength 是目标字符串的最终长度。
  • padString 是用于填充的字符串(如果字符串长度不够,使用这个字符串填充,直到目标长度为止)。

padStart(2, '0') 中,意思是如果原字符串的长度小于 2,则用 '0' 在字符串的开头进行填充,直到字符串的长度为 2。

  • 案列:
'5'.padStart(2, '0');  // '05'
'12'.padStart(2, '0'); // '12'
'123'.padStart(5, '0'); // '00123'
七、实现高亮当前日期,给日期添加点击事件,并高亮显示
  • calendar.wxml
   <view class="dates">
        <block wx:for="{{days}}" wx:key="index">
          <view class="date {{item.isToday ? 'highlight-today' : ''}} {{isChooseDate==item.day ? 'choose-day' : ''}}" bindtap="showEventDetail" data-day="{{item}}">{{item.day}}</view>
        </block>
      </view>
  • calendar.js
 loadCalendar() {
    const {
      year,
      month
    } = this.data;
    // 获取当月的第一天是星期几
    const firstDay = new Date(year, month - 1, 1).getDay();
    // 获取当月的天数
    const totalDays = new Date(year, month, 0).getDate();
    // 获取今天的日期(用于高亮显示)
    const today = new Date();
    const todayDate = `${today.getFullYear()}-${(today.getMonth() + 1).toString().padStart(2, '0')}-${today.getDate().toString().padStart(2, '0')}`;

    // 创建日期数组
    const days = [];
    // 填充空白日期
    for (let i = 0; i < firstDay; i++) {
      days.push('');
    }
    // 填充实际日期
    for (let i = 1; i <= totalDays; i++) {
      const day = `${year}-${month.toString().padStart(2, '0')}-${i.toString().padStart(2, '0')}`;
      const isToday = day === todayDate;  // 如果是今天的日期,则标记为今天
      days.push({ day: i,isToday });
    }

    this.setData({
      days,
      selectedDate:this.data.selectedDate?this.data.selectedDate:todayDate
    });
  },

  changeMonth(event) {
    const direction = event.currentTarget.dataset.direction;
    let {
      year,
      month
    } = this.data;

    if (direction === 'prev') {
      month--;
      if (month < 1) {
        month = 12;
        year--;
      }
    } else if (direction === 'next') {
      month++;
      if (month > 12) {
        month = 1;
        year++;
      }
    }

    this.setData({
      year,
      month,
      isChooseDate:''
    }, () => {
      this.loadCalendar();
    });

  },

  // 显示事件详情
  showEventDetail(event) {
    const day = event.currentTarget.dataset.day.day;
    const selectedDate = `${this.data.year}-${this.data.month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`;
 
    this.setData({
      isChooseDate:day,
      selectedDate:selectedDate
    })

  },
  • calendar.scss
  .choose-day{
    border:1px solid  #65b778;
    color: #65b778;
    font-weight: bold;
    background-color: #fff;
  }
  .highlight-today{
    background-color: #65b778;
    color: #fff;
    font-weight: bold;
  }
  • 效果图

在这里插入图片描述

八、滑动切换日历月份

calendar.html

<view class="calendar"  bindtouchstart="touchStart"   bindtouchend="touchEnd"></view>

calendar.js

  data: {
    startX: 0, // 触摸起始位置
    startY: 0, // 触摸起始位置
    minSwipeDistance: 50 // 设置最小滑动距离,单位:px
  },
    
        // 触摸开始事件
  touchStart(e) {
    this.setData({
      startX: e.touches[0].clientX,
      startY: e.touches[0].clientY
    });
  },
  // 触摸结束事件
  touchEnd(e) {
    const endX = e.changedTouches[0].clientX;
    const endY = e.changedTouches[0].clientY;

    const dx = endX - this.data.startX; // 水平滑动距离
    const dy = endY - this.data.startY; // 垂直滑动距离

    // 判断是否为左右滑动(忽略上下滑动)
    if (Math.abs(dx) > Math.abs(dy)) {
      if (Math.abs(dx) >= this.data.minSwipeDistance) { // 只有当滑动距离超过阈值时才切换,防止误触
        if (dx > 0) {
          // 向右滑动,切换到上个月
          this.changeMonthBySwipe('prev');
        } else if (dx < 0) {
          // 向左滑动,切换到下个月
          this.changeMonthBySwipe('next');
        }
      }
    }
  },
  // 根据滑动方向切换月份
  changeMonthBySwipe(direction) {
    let {
      year,
      month
    } = this.data;

    if (direction === 'prev') {
      month--;
      if (month < 1) {
        month = 12;
        year--;
      }
    } else if (direction === 'next') {
      month++;
      if (month > 12) {
        month = 1;
        year++;
      }
    }

    this.setData({
      year,
      month,
      isChooseDate: ''
    }, () => {
      this.loadCalendar();
    });
  },
      
### 微信小程序日历签到功能实现 #### 1. 基础环境搭建 为了创建一个具有日历签到功能的小程序,需先设置好开发环境。确保已安装最新版本的微信开发者工具,并配置好项目基本信息。 #### 2. 创建页面布局 构建基础UI框架,包括顶部导航栏、中间展示区域以及底部操作按钮等部分。对于日历组件而言,通常会采用网格形式排列各天数格子,以便于用户直观查看当月每一天的状态。 ```html <!-- index.wxml --> <view class="calendar"> <!-- 显示当前月份 --> <text>{{currentMonth}}</text> <!-- 日历表头 --> <view class="weekdays"> <block wx:for="{{['一', '二', '三', '四', '五', '六', '日']}}" wx:key="index"> <view class="weekday">{{item}}</view> </block> </view> <!-- 日历主体 --> <view class="dates"> <block wx:for="{{dateList}}" wx:key="uniqueKey"> <view class="day {{item.signed ? 'signed' : ''}}"> <text>{{item.day}}</text> <image wx:if="{{item.signed}}" src="/images/check.png"></image> <!-- 已签到标记 --> </view> </block> </view> </view> ``` #### 3. 数据处理逻辑 编写JavaScript脚本来控制数据流,比如初始化加载时计算本月有多少天、哪些日子已经完成签到了等等。这里还需要考虑不同年份闰年的特殊情况。 ```javascript // index.js Page({ data: { currentYear: new Date().getFullYear(), currentMonth: '', dateList: [] }, onLoad() { this.updateCalendar(); }, updateCalendar() { const now = new Date(this.data.currentYear, moment().month(), 1); let daysInMonth = moment(now).daysInMonth(); // 构建日期数组 let dates = []; for (let i = 0; i < daysInMonth; ++i) { let dayObj = {}; dayObj.day = i + 1; dayObj.signed = false; // 模拟查询数据库判断某一天是否已被签到 if(/* 查询条件 */) { dayObj.signed = true; } dates.push(dayObj); } this.setData({ currentMonth: `${this.data.currentYear} 年 ${moment(now).format('M')} 月`, dateList: dates, }); } }); ``` #### 4. 添加交互事件 允许用户点击某个具体的日子来进行签到动作。这涉及到前后端之间的通信机制设计,前端负责收集输入信息并通过API发送给服务器;而后端则要对接收到的数据进行验证保存,并返回成功与否的消息反馈给客户端。 ```json { "usingComponents": {}, "navigationBarTitleText": "每日签到", } ``` ```css /* index.wxss */ .calendar { ... } .weekdays .weekday { width: calc(100% / 7); text-align:center;} .dates .day{ position:relative;width:calc(100%/7);} .dates .day.text{text-align:center;line-height:40rpx;height:40rpx;} .dates .day image{position:absolute;top:-5rpx;left:50%;transform:translateX(-50%);} /* 居中显示*/ .signed::after{/* 自定义样式表示已签到 */} ``` 以上就是关于如何在微信小程序内集成简单版的日历签到系统的介绍[^1]。此方案不仅能够满足日常需求,同时也具备良好的扩展性和灵活性,方便后续进一步优化升级。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值