经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » JavaScript » 查看文章
一个简易的小程序日历组件
来源:cnblogs  作者:similar  时间:2021/6/7 9:12:06  对本文有异议

 

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

 

一、效果图如下:

 

 

二、业务场景介绍

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

 

三、需求实现

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

 

主要功能:

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

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

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

 

 

四、主要代码

 

1.  calendar.wxml

  1. <view class="calendar-box">
  2. <view class="head-box">
  3. <view class="title-box">{{title}}</view>
  4. <view class="week-box">
  5. <view class="week-item"></view>
  6. <view class="week-item"></view>
  7. <view class="week-item"></view>
  8. <view class="week-item"></view>
  9. <view class="week-item"></view>
  10. <view class="week-item"></view>
  11. <view class="week-item"></view>
  12. </view>
  13. </view>
  14. <view class="date-box">
  15. <view
  16. bindtap="clickItem"
  17. data-date="{{day.date}}"
  18. class="date-item {{currentDate == day.date ? 'active' : ''}}"
  19. wx:for="{{daysArray}}" wx:for-item="day"
  20. wx:key="index">
  21. <view class="top-text" wx:if="{{day.topText}}">{{day.topText}}</view>
  22. {{day.date}}
  23. <view class="bottom-text" wx:if="{{day.bottomText}}">{{day.bottomText}}</view>
  24. </view>
  25. </view>
  26. </view>

 

2. calendar.js

  1. // components/calendar/calendar.js
  2. Component({
  3. /**
  4. * 组件的属性列表
  5. */
  6. properties: {
  7. defaultDate: {
  8. type: String,
  9. observer () {
  10. this.getCurrentDaysAndWeekStart();
  11. this.renderDate();
  12. this.triggerEvent('formatter', this.data.daysArray);
  13. }
  14. },
  15. isDataChange: {
  16. type: Boolean,
  17. value: false,
  18. observer () {
  19. this.triggerEvent('formatter', this.data.daysArray);
  20. }
  21. },
  22. daysData: {
  23. type: Array,
  24. observer (newVal) {
  25. if (newVal.length > 0) {
  26. this.setData({ daysArray: newVal });
  27. }
  28. }
  29. }
  30. },
  31. /**
  32. * 组件的初始数据
  33. */
  34. data: {
  35. Y: '', //
  36. M: '', //
  37. D: '', //
  38. W: '', // 星期
  39. firstDayWeek: '', // 当前月第一天星期几
  40. lastDayWeek: '', // 当前月最后一天星期几
  41. daysCount: 0, // 总天数
  42. daysArray: [], // 日历中天数数组
  43. title: '',
  44. currentDate: '0'
  45. },
  46. /**
  47. * 组件的方法列表
  48. */
  49. methods: {
  50. // 获取当前月的天数,以及当前月第一天是星期几,最后一天是星期几
  51. getCurrentDaysAndWeekStart () {
  52. let dateString = this.properties.defaultDate;
  53. let today = new Date();
  54. if (dateString) {
  55. today = new Date(dateString);
  56. }
  57. let Y = today.getFullYear();
  58. let M = today.getMonth() + 1;
  59. let D = today.getDate();
  60. let daysCount = new Date(Y, M, 0).getDate(); // 当前月最后一天日期,即当前月的天数
  61. let firstDayWeek = new Date(Y, M - 1, 1).getDay(); // 第一天星期几
  62. let lastDayWeek = new Date(Y, M, 0).getDay(); // 最后一天星期几
  63. this.setData({
  64. Y: Y,
  65. M: M,
  66. D: D,
  67. firstDayWeek: firstDayWeek,
  68. lastDayWeek: lastDayWeek,
  69. daysCount: daysCount,
  70. title: `${Y}年${M}月`
  71. });
  72. },
  73. // 根据总天数和第一天星期几,最后一天星期几,渲染日历天数数组
  74. renderDate () {
  75. let firstDayWeek = this.data.firstDayWeek;
  76. let lastDayWeek = this.data.lastDayWeek;
  77. let daysCount = this.data.daysCount;
  78. let days = []; // 当前月总天数数组
  79. for (let i = 1; i <= daysCount; i++) {
  80. days.push({
  81. date: i.toString(),
  82. topText: '',
  83. bottomText: ''
  84. });
  85. }
  86. // 补全前面 (因为一周七天,如果第一天是星期三,则需要把星期一和星期二数据补全)
  87. for (let i = 0; i < firstDayWeek; i++) {
  88. days.unshift({
  89. date: '',
  90. topText: '',
  91. bottomText: ''
  92. });
  93. }
  94. // 补全后面 (因为一周七天,如果最后一天是星期五,则需要把星期六和星期天数据补全)
  95. for (let i = lastDayWeek; i <= 7; i++) {
  96. days.push({
  97. date: '',
  98. topText: '',
  99. bottomText: ''
  100. });
  101. }
  102. this.setData({ daysArray: days });
  103. },
  104. // 点击单个日期事件
  105. clickItem (event) {
  106. let date = event.currentTarget.dataset.date;
  107. if (date) {
  108. this.setData({ currentDate: date });
  109. this.triggerEvent('select', `${this.data.Y}-${this.data.M}-${date}`);
  110. }
  111. }
  112. }
  113. })

 

 

3. calendar.wxss

  1. /* components/calendar/calendar.wxss */
  2. .calendar-box {
  3. background-color: #ffffff;
  4. padding: 10rpx;
  5. color: #323233;
  6. }
  7. .head-box {
  8. box-shadow: 0 2px 10px rgb(125 126 128 / 16%);
  9. }
  10. .title-box {
  11. padding: 20rpx 0 40rpx 0;
  12. text-align: center;
  13. font-size: 14px;
  14. }
  15. .week-box {
  16. display: flex;
  17. justify-content: space-between;
  18. font-size: 12px;
  19. padding-bottom: 20rpx;
  20. }
  21. .week-item {
  22. width: 100%;
  23. text-align: center;
  24. }
  25. .date-box {
  26. display: flex;
  27. flex-wrap: wrap;
  28. justify-content: space-between;
  29. }
  30. .date-item {
  31. display: flex;
  32. flex-direction: column;
  33. align-items: center;
  34. justify-content: center;
  35. height: 125rpx;
  36. width: 14.285%;
  37. border-radius: 10rpx;
  38. font-size: 12px;
  39. }
  40. .top-text, .bottom-text {
  41. font-size: 8px;
  42. color: red;
  43. }
  44. .active {
  45. background-color: pink;
  46. }

 

原文链接:http://www.cnblogs.com/similar/p/14833872.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号