当前位置:
首页 > temp > JavaScript教程 >
-
一个简易的小程序日历组件
代码仓库地址:https://github.com/imxiaoer/WeChatMiniCalendar
一、效果图如下:
二、业务场景介绍
客户原始需求:用户需要知道在选中的月份中,哪些日期是有客户预约的,并且显示当天预约人数,点击有预约的日期则进入预约信息详细页,详细页内可以新建预约;点击没有预约的日期则直接进入新建预约页面。
三、需求实现
因为项目用的是vant的小程序ui组件,所以刚开始想的是用vant的日历组件来实现此需求。经过几番尝试后,始终实现不了 formatter 的动态数据渲染,最后放弃了(如有大佬已实现此功能,麻烦留言分享下你的解决方案,谢谢),然后自己写了一个日历组件。
主要功能:
1. 根据传入的日期,渲染当月日历,如传入 2021/6/1,则渲染2021年6月份的日历
2. 点击单个日期,返回具体年月日,并且被点击日期变色
3. 根据用户数据,动态渲染日历标注。传入的日期变更,或者是用户数据变更,都会重新渲染日历及标注。上面效果图下方的【改日期】和 【改数据】就是用来测试这个功能的。
四、主要代码
1. calendar.wxml
<view class="calendar-box"> <view class="head-box"> <view class="title-box">{{title}}</view> <view class="week-box"> <view class="week-item">日</view> <view class="week-item">一</view> <view class="week-item">二</view> <view class="week-item">三</view> <view class="week-item">四</view> <view class="week-item">五</view> <view class="week-item">六</view> </view> </view> <view class="date-box"> <view bindtap="clickItem" data-date="{{day.date}}" class="date-item {{currentDate == day.date ? 'active' : ''}}" wx:for="{{daysArray}}" wx:for-item="day" wx:key="index"> <view class="top-text" wx:if="{{day.topText}}">{{day.topText}}</view> {{day.date}} <view class="bottom-text" wx:if="{{day.bottomText}}">{{day.bottomText}}</view> </view> </view> </view>
2. calendar.js
// components/calendar/calendar.js Component({ /** * 组件的属性列表 */ properties: { defaultDate: { type: String, observer () { this.getCurrentDaysAndWeekStart(); this.renderDate(); this.triggerEvent('formatter', this.data.daysArray); } }, isDataChange: { type: Boolean, value: false, observer () { this.triggerEvent('formatter', this.data.daysArray); } }, daysData: { type: Array, observer (newVal) { if (newVal.length > 0) { this.setData({ daysArray: newVal }); } } } }, /** * 组件的初始数据 */ data: { Y: '', // 年 M: '', // 月 D: '', // 日 W: '', // 星期 firstDayWeek: '', // 当前月第一天星期几 lastDayWeek: '', // 当前月最后一天星期几 daysCount: 0, // 总天数 daysArray: [], // 日历中天数数组 title: '', currentDate: '0' }, /** * 组件的方法列表 */ methods: { // 获取当前月的天数,以及当前月第一天是星期几,最后一天是星期几 getCurrentDaysAndWeekStart () { let dateString = this.properties.defaultDate; let today = new Date(); if (dateString) { today = new Date(dateString); } let Y = today.getFullYear(); let M = today.getMonth() + 1; let D = today.getDate(); let daysCount = new Date(Y, M, 0).getDate(); // 当前月最后一天日期,即当前月的天数 let firstDayWeek = new Date(Y, M - 1, 1).getDay(); // 第一天星期几 let lastDayWeek = new Date(Y, M, 0).getDay(); // 最后一天星期几 this.setData({ Y: Y, M: M, D: D, firstDayWeek: firstDayWeek, lastDayWeek: lastDayWeek, daysCount: daysCount, title: `${Y}年${M}月` }); }, // 根据总天数和第一天星期几,最后一天星期几,渲染日历天数数组 renderDate () { let firstDayWeek = this.data.firstDayWeek; let lastDayWeek = this.data.lastDayWeek; let daysCount = this.data.daysCount; let days = []; // 当前月总天数数组 for (let i = 1; i <= daysCount; i++) { days.push({ date: i.toString(), topText: '', bottomText: '' }); } // 补全前面 (因为一周七天,如果第一天是星期三,则需要把星期一和星期二数据补全) for (let i = 0; i < firstDayWeek; i++) { days.unshift({ date: '', topText: '', bottomText: '' }); } // 补全后面 (因为一周七天,如果最后一天是星期五,则需要把星期六和星期天数据补全) for (let i = lastDayWeek; i <= 7; i++) { days.push({ date: '', topText: '', bottomText: '' }); } this.setData({ daysArray: days }); }, // 点击单个日期事件 clickItem (event) { let date = event.currentTarget.dataset.date; if (date) { this.setData({ currentDate: date }); this.triggerEvent('select', `${this.data.Y}-${this.data.M}-${date}`); } } } })
3. calendar.wxss
/* components/calendar/calendar.wxss */ .calendar-box { background-color: #ffffff; padding: 10rpx; color: #323233; } .head-box { box-shadow: 0 2px 10px rgb(125 126 128 / 16%); } .title-box { padding: 20rpx 0 40rpx 0; text-align: center; font-size: 14px; } .week-box { display: flex; justify-content: space-between; font-size: 12px; padding-bottom: 20rpx; } .week-item { width: 100%; text-align: center; } .date-box { display: flex; flex-wrap: wrap; justify-content: space-between; } .date-item { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 125rpx; width: 14.285%; border-radius: 10rpx; font-size: 12px; } .top-text, .bottom-text { font-size: 8px; color: red; } .active { background-color: pink; }
来源:https://www.cnblogs.com/similar/p/14833872.html
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
关于JS定时器的整理
JS中使用Promise.all控制所有的异步请求都完
js中字符串的方法
import-local执行流程与node模块路径解析流程
检测数据类型的四种方法
js中数组的方法,32种方法
前端操作方法
数据类型
window.localStorage.setItem 和 localStorage.setIte
如何完美解决前端数字计算精度丢失与数