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

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

  • 可以创建一个日历组件,来展示当前月份的日期,并支持切换月份的功能。
一、目录结构
js 复制代码
/pages
  /calendar
    calendar.wxml
    calendar.scss
    calendar.js
    calendar.json
二、calendar.wxml
html 复制代码
  <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
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
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') 来确保日期和月份都是两位数格式。

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

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

  • 案列:
js 复制代码
'5'.padStart(2, '0');  // '05'
'12'.padStart(2, '0'); // '12'
'123'.padStart(5, '0'); // '00123'
七、实现高亮当前日期,给日期添加点击事件,并高亮显示
  • calendar.wxml
html 复制代码
   <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
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
css 复制代码
  .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

html 复制代码
<view class="calendar"  bindtouchstart="touchStart"   bindtouchend="touchEnd"></view>

calendar.js

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();
    });
  },
      
相关推荐
萧寂1732 小时前
微信小程序自定义轮播图指示点样式
微信小程序·小程序
SuperherRo10 小时前
自动化反编译微信小程序工具-e0e1-wx
微信小程序·自动化·hook·反编译
R_yy11 小时前
微信小程序开发——视频播放实现(本地视频或者云端视频均可)
前端·微信小程序·小程序
京河小蚁13 小时前
解决Moodo调节心情模块-大声喊出来无法测量出音频分贝
微信小程序·音视频·ai编程·cursor
低代码布道师15 小时前
加油站小程序实战教程03站点管理
低代码·小程序
蒜香拿铁16 小时前
小程序参数获取方式
前端·微信小程序
V+zmm1013418 小时前
智慧物流小程序(论文源码调试讲解)
java·数据库·微信小程序·小程序·毕业设计
霍格沃兹测试开发学社测试人社区18 小时前
性能测试丨微信小程序性能优化指南
性能优化·微信小程序·小程序
猿毕设21 小时前
【FL0100】基于SSM微信小程序的走失人员的报备平台
java·spring boot·后端·python·微信小程序·小程序
猿毕设21 小时前
【FL0091】基于SSM和微信小程序的社区二手物品交易小程序
java·spring boot·后端·python·微信小程序·小程序