当前位置: 首页 > article >正文

微信小程序实现自定义日历功能

文章目录

    • 1. 创建日历组件实现步骤:
    • 2. 代码实现过程
    • 3. 实现效果图
    • 4. 关于作者其它项目视频教程介绍

1. 创建日历组件实现步骤:

  1. 创建日历组件:首先,你需要创建一个日历组件,包含显示日期的逻辑。
  2. 样式设计:为日历组件设计样式,使其看起来美观。
  3. 事件处理:添加事件处理程序,以便用户可以选择日期。

2. 代码实现过程

  1. 编写calendar.wxml布局
<!-- calendar.wxml -->
<navigation-bar title="日历控件" back="{{false}}" color="#FFFFFF" background="#e6142c"></navigation-bar>
  <!-- 日历部分 -->
  <view class="calendar">
    <!-- 日历头部 -->
    <view class="calendar-header">
      <view class="arrow" bindtap="prevMonth"></view>
      <view class="date-title">{{year}}年{{month}}月</view>
      <view class="arrow" bindtap="nextMonth"></view>
    </view>

    <!-- 星期标题 -->
    <view class="weekday-row">
      <view class="weekday" wx:for="{{weekdays}}" wx:key="*this">{{item}}</view>
    </view>

    <!-- 日期格子 -->
    <view class="date-rows">
      <view class="date-row" wx:for="{{dateList}}" wx:for-item="row" wx:key="index">
        <view class="date-cell {{item.currentMonth ? '' : 'other-month'}} {{item.isToday ? 'today' : ''}} {{item.selected ? 'selected' : ''}}" wx:for="{{row}}" wx:key="date" bindtap="selectDate" data-date="{{item.date}}">
          {{item.day}}
        </view>
      </view>
    </view>
  </view>

  1. 编写calendar.wxss样式
/* calendar.wxss */
page {
  height: 100vh;
  display: flex;
  flex-direction: column;
  background-color: #f5f5f5;
}


.calendar {
  background: #f5f5f5;
  border-radius: 10rpx;
  padding: 20rpx;
}

.calendar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20rpx 0;
}

.date-title {
  font-size: 32rpx;
  font-weight: bold;
}

.arrow {
  padding: 10rpx 20rpx;
  color: #666;
}

.weekday-row {
  display: flex;
  border-bottom: 1rpx solid #eee;
  padding-bottom: 10rpx;
  margin-bottom: 10rpx;
}

.weekday {
  flex: 1;
  text-align: center;
  font-size: 28rpx;
  color: #666;
}

.date-rows {
  display: flex;
  flex-direction: column;
}

.date-row {
  display: flex;
  margin: 5rpx 0;
}

.date-cell {
  flex: 1;
  text-align: center;
  padding: 15rpx 0;
  font-size: 28rpx;
  position: relative;
  height: 65rpx;
  line-height: 65rpx;
  margin: 5rpx;
}

.selected {
  background: #e6142c;
  color: #fff !important;
  /* 确保选中时文字颜色为白色 */
  border-radius: 50%;
}


/* 确保今天的样式和选中样式可以共存 */
.today {
  color: #e6142c;
  font-weight: bold;
}

.today.selected {
  color: #fff !important;
  background: #e6142c;
}

/* 其他月份日期的样式 */
.other-month {
  color: #ccc;
}

.other-month.selected {
  background: #1aad19;
  color: #fff !important;
}
  1. 编写calendar.js具体逻辑实现
// calendar.js
Page({
  data: {
    year: 2024,
    month: 1,
    day: 1,
    weekdays: ['日', '一', '二', '三', '四', '五', '六'],
    dateList: [],
    selectedDate: null,
    dateStr: '',
  },
  
  onLoad() {
    // 初始化当前日期
    const now = new Date()
    this.setData({
      year: now.getFullYear(),
      month: now.getMonth() + 1,
      selectedDate: now // 设置当前日期为选中状态
    }, () => {
      this.generateDateList()
    })

    wx.showToast({
      title: this.data.selectedDate.toLocaleDateString(),
      icon:"none"
    })
  },



  // 生成日历数据
  generateDateList() {
    const {
      year,
      month
    } = this.data
    const dateList = []

    // 获取当月第一天和最后一天
    const firstDay = new Date(year, month - 1, 1)
    const lastDay = new Date(year, month, 0)

    // 获取当月第一天是星期几
    const firstDayWeek = firstDay.getDay()

    // 获取上个月的最后几天
    const prevMonthLastDay = new Date(year, month - 1, 0).getDate()

    // 当前日期
    const today = new Date()
    const currentDateStr = today.toDateString()

    // 填充上个月的日期
    let row = []
    for (let i = 0; i < firstDayWeek; i++) {
      const day = prevMonthLastDay - firstDayWeek + i + 1
      const date = new Date(year, month - 2, day)
      row.push({
        day,
        date: date,
        currentMonth: false,
        isToday: date.toDateString() === currentDateStr,
        selected: this.data.selectedDate && date.toDateString() === this.data.selectedDate.toDateString()
      })
    }

    // 填充当月日期
    for (let day = 1; day <= lastDay.getDate(); day++) {
      const date = new Date(year, month - 1, day)
      row.push({
        day,
        date: date,
        currentMonth: true,
        isToday: date.toDateString() === currentDateStr,
        selected: this.data.selectedDate && date.toDateString() === this.data.selectedDate.toDateString()
      })

      if (row.length === 7) {
        dateList.push(row)
        row = []
      }
    }

    // 填充下个月的日期
    let nextMonthDay = 1
    while (row.length < 7) {
      const date = new Date(year, month, nextMonthDay)
      row.push({
        day: nextMonthDay++,
        date: date,
        currentMonth: false,
        isToday: date.toDateString() === currentDateStr,
        selected: this.data.selectedDate && date.toDateString() === this.data.selectedDate.toDateString()
      })
    }
    dateList.push(row)

    this.setData({
      dateList
    })
  },

  // 选择日期
  selectDate(e) {
    const selectedDate = new Date(e.currentTarget.dataset.date)

    this.setData({
      selectedDate: selectedDate
    }, () => {
      this.generateDateList()

      //格式化日期
      const date = new Date(selectedDate.toLocaleDateString())
      
     
      wx.showToast({
        title: selectedDate.toLocaleDateString(),
        icon:"none"
      })
     
    })
  },

  // 生成日历数据
  generateDateList() {
    const {
      year,
      month
    } = this.data
    const dateList = []

    // 获取当月第一天和最后一天
    const firstDay = new Date(year, month - 1, 1)
    const lastDay = new Date(year, month, 0)

    // 获取当月第一天是星期几
    const firstDayWeek = firstDay.getDay()

    // 获取上个月的最后几天
    const prevMonthLastDay = new Date(year, month - 1, 0).getDate()

    // 当前日期
    const today = new Date()
    const currentDateStr = today.toDateString()

    // 选中的日期字符串(用于比较)
    const selectedDateStr = this.data.selectedDate ? this.data.selectedDate.toDateString() : ''

    // 填充上个月的日期
    let row = []
    for (let i = 0; i < firstDayWeek; i++) {
      const day = prevMonthLastDay - firstDayWeek + i + 1
      const date = new Date(year, month - 2, day)
      const dateStr = date.toDateString()
      row.push({
        day,
        date: dateStr,
        currentMonth: false,
        isToday: dateStr === currentDateStr,
        selected: selectedDateStr && dateStr === selectedDateStr
      })
    }

    // 填充当月日期
    for (let day = 1; day <= lastDay.getDate(); day++) {
      const date = new Date(year, month - 1, day)
      const dateStr = date.toDateString()
      row.push({
        day,
        date: dateStr,
        currentMonth: true,
        isToday: dateStr === currentDateStr,
        selected: selectedDateStr && dateStr === selectedDateStr
      })

      if (row.length === 7) {
        dateList.push(row)
        row = []
      }
    }

    // 填充下个月的日期
    let nextMonthDay = 1
    while (row.length < 7) {
      const date = new Date(year, month, nextMonthDay)
      const dateStr = date.toDateString()
      row.push({
        day: nextMonthDay++,
        date: dateStr,
        currentMonth: false,
        isToday: dateStr === currentDateStr,
        selected: selectedDateStr && dateStr === selectedDateStr
      })
    }
    if (row.length > 0) {
      dateList.push(row)
    }

    this.setData({
      dateList
    })
  },

  // 上个月
  prevMonth() {
    let {
      year,
      month
    } = this.data
    if (month === 1) {
      year--
      month = 12
    } else {
      month--
    }
    this.setData({
      year,
      month
    }, () => {
      this.generateDateList()
    })
  },

  // 下个月
  nextMonth() {
    let {
      year,
      month
    } = this.data
    if (month === 12) {
      year++
      month = 1
    } else {
      month++
    }
    this.setData({
      year,
      month
    }, () => {
      this.generateDateList()
    })
  }

  
});

3. 实现效果图

在这里插入图片描述

4. 关于作者其它项目视频教程介绍

  1. Android新闻资讯app实战:https://www.bilibili.com/video/BV1CA1vYoEad/?vd_source=984bb03f768809c7d33f20179343d8c8
  2. Androidstudio开发购物商城实战:https://www.bilibili.com/video/BV1PjHfeXE8U/?vd_source=984bb03f768809c7d33f20179343d8c8
  3. Android开发备忘录记事本实战:https://www.bilibili.com/video/BV1FJ4m1u76G?vd_source=984bb03f768809c7d33f20179343d8c8&spm_id_from=333.788.videopod.sections
  4. Androidstudio底部导航栏实现:https://www.bilibili.com/video/BV1XB4y1d7et/?spm_id_from=333.337.search-card.all.click&vd_source=984bb03f768809c7d33f20179343d8c8
  5. Android使用TabLayout+ViewPager2实现左右滑动切换:https://www.bilibili.com/video/BV1Mz4y1c7eX/?spm_id_from=333.337.search-card.all.click&vd_source=984bb03f768809c7d33f20179343d8c8
  6. 为什么要封装BaseActivity?: https://www.bilibili.com/video/BV11S411A7R5/?vd_source=984bb03f768809c7d33f20179343d8c8
  7. 为什么要封装BaseFragment?:https://www.bilibili.com/video/BV1Um421G7yC/?vd_source=984bb03f768809c7d33f20179343d8c8

http://www.kler.cn/a/515316.html

相关文章:

  • cookie 与 session -- 会话管理
  • HTTP 配置与应用(局域网)
  • Linux中关于glibc包编译升级导致服务器死机或者linux命令无法使用的情况
  • 可视化-numpy实现线性回归和梯度下降法
  • Vue3初学之Element Plus Dialog对话框,Message组件,MessageBox组件
  • 【0x0052】HCI_Write_Extended_Inquiry_Response命令详解
  • 循环队列(C语言)
  • 3.CSS的背景
  • 【json_object】mysql中json_object函数过长,显示不全
  • 安装线程自由(无GIL锁)Python及Pytorch方法
  • JavaScript系列(37)-- Service Workers详解
  • 有限元分析学习——Anasys Workbanch第一阶段笔记(15)接触间隙处理与赫兹接触
  • DELL EDI:需求分析及注意事项
  • vue3+webOffice合集
  • HarmonyOS Next 应用UI生成工具介绍
  • IP属地与视频定位位置不一致:现象解析与影响探讨
  • orbbec 奥比中光相机单目及多目调用方式python代码
  • 「全网最细 + 实战源码案例」设计模式——工厂方法模式
  • 如何确保爬虫不违反苏宁的使用条款?
  • 机器学习之决策树(DecisionTree——C4.5)
  • StarRocks强大的实时数据分析
  • 网络安全解决方案分享:推荐十款网络准入控制系统,保护企业网络安全
  • 青少年编程与数学 02-007 PostgreSQL数据库应用 15课题、备份与还原
  • 新年好(Dijkstra+dfs/全排列)
  • excel导入数据处理前端
  • 安卓程序作为web服务端的技术实现(二):Room 实现数据存储