2021年6月1日星期二

因为解决不了vant日历组件动态渲染formatter的问题,于是自己撸了一个简易的小程序日历组件

 

代码仓库地址:https://github.com/imxiaoer/WeChatMiniCalendar

 

一、效果图如下:

 

 

二、业务场景介绍

客户原始需求:用户需要知道在选中的月份中,哪些日期是有客户预约的,并且显示当天预约人数,点击有预约的日期则进入预约信息详细页,详细页内可以新建预约;点击没有预约的日期则直接进入新建预约页面。

 

三、需求实现

因为项目用的是vant的小程序ui组件,所以刚开始想的是用vant的日历组件来实现此需求。经过几番尝试后,始终实现不了 formatter 的动态数据渲染,最后放弃了(如有大佬已实现此功能,麻烦留言分享下你的解决方案,谢谢),然后自己写了一个日历组件。

 

主要功能:

1.  根据传入的日期,渲染当月日历,如传入 2021/6/1,则渲染2021年6月份的日历

2. 点击单个日期,返回具体年月日,并且被点击日期变色

3. 根据用户数据,动态渲染日历标注。传入的日期变更,或者是用户数据变更,都会重新渲染日历及标注。上面效果图下方的【改日期】和 【改数据】就是用来测试这个功能的。

 

 

四、主要代码

 

1.  calendar.w

<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.jsComponent({ /** * 组件的属性列表 */ 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;}

 

因为网络的原因,打不开github,所以暂时没法上传demo代码,之后代码上传到GitHub了会在文章顶部贴出地址,谢谢关注。

 









原文转载:http://www.shaoqun.com/a/775056.html

跨境电商:https://www.ikjzd.com/

百思买:https://www.ikjzd.com/w/394

bap:https://www.ikjzd.com/w/1492


代码仓库地址:https://github.com/imxiaoer/WeChatMiniCalendar一、效果图如下:二、业务场景介绍客户原始需求:用户需要知道在选中的月份中,哪些日期是有客户预约的,并且显示当天预约人数,点击有预约的日期则进入预约信息详细页,详细页内可以新建预约;点击没有预约的日期则直接进入新建预约页面。三、需求实现因为项目用的是vant的小程序ui组件,所以刚开始想的是用v
名人堂是什么:https://www.ikjzd.com/w/1082
Wish平台如何选品?:https://www.ikjzd.com/articles/145255
想要做好Ebay,这些知识必须了解!:https://www.ikjzd.com/articles/145254
心怡:https://www.ikjzd.com/w/1327
parser:https://www.ikjzd.com/w/680
口述:老汉不巧撞儿媳洗澡 父子不来往老汉儿媳父子:http://lady.shaoqun.com/m/a/37362.html
口述:初恋女友嫁给了我叔叔:http://www.30bags.com/a/252765.html
老师抬起臀部让我进去 掀开老师湿润的短裙:http://www.30bags.com/m/a/249910.html
避雷:亚马逊"Request a Review"按钮正确使用解答:https://www.ikjzd.com/articles/145252

没有评论:

发表评论