[前端] 微信小程序自定义时间段picker选择器

2113 0
王子 2022-10-21 15:13:27 | 显示全部楼层 |阅读模式
本文实例为大家分享了微信小程序自定义时间段picker选择器的具体代码,供大家参考,具体内容如下
想实现一个可以选择年份和时间段的日期选择器,如下所示


微信小程序自带的picker组件虽然能实现如上的内容,但不能实现样式的修改,不太符合小程序的设计主题,所以考虑了以下两种方法来实现如上的设计。
1.自定义date-picker
把要实现的date-picker封装为一个组件,组件内套用小程序自带的picker-view组件,其中picker_view-column表示不同的选择列,这样可以方便地实现样式的自定义。
实现效果:


具体实现
wxml文件:
  1. <view class="mask" wx:if="{{isShow}}" catchtap="cancel">
  2. <view class="content" style="height:800rpx" animation="{{animation}}">
  3.   <view class="top">
  4.    <view class="top-text top-left-color" hover-class="top-left-color-hover" catchtap="cancel">取消</view>
  5.    <view class="top-text top-right-color" hover-class="top-right-color-hover" catchtap="confirm">确定</view>
  6.   </view>
  7.   <picker-view style="width: 100%; height: 80%;" value="{{value}}" bindchange="change" catchtap="no">
  8.    <picker-view-column>
  9.     <view wx:for="{{date_list}}" wx:key="date_list" class="item">{{item}}</view>
  10.    </picker-view-column>
  11.    <picker-view-column>
  12.     <view wx:for="{{time_list}}" wx:key="time_list" class="item">{{item}}</view>
  13.    </picker-view-column>
  14.   lt;/picker-view>
  15. </view>
  16. </view>
复制代码
wxss文件:
  1. .mask {
  2. position: fixed;
  3. width: 100%;
  4. height: 100%;
  5. left: 0;
  6. right: 0;
  7. top: 0;
  8. bottom: 0;
  9. display: flex;
  10. background-color: rgba(0, 0, 0, 0.7);
  11. z-index: 9999;
  12. flex-direction: column;
  13. justify-content: flex-end;
  14. }
  15. .content {
  16. display: flex;
  17. flex-direction: column;
  18. width: 100%;
  19. background: white;
  20. border-top-right-radius: 20rpx;
  21. border-top-left-radius: 20rpx;
  22. }
  23. .top {
  24. display: flex;
  25. flex-direction: row;
  26. justify-content: space-between;
  27. align-items: center;
  28. height: 100rpx;
  29. border-bottom: 1rpx solid #d3cfcf;
  30. }
  31. .top-text {
  32. font-size: 30rpx;
  33. width: 150rpx;
  34. height: 100rpx;
  35. display: flex;
  36. flex-direction: row;
  37. justify-content: center;
  38. align-items: center;
  39. }
  40. .top-left-color {
  41. color: #878787;
  42. }
  43. .top-left-color-hover {
  44. color: #f1eaea;
  45. }
  46. .top-right-color {
  47. color: #1296DB;
  48. }
  49. .top-right-color-hover {
  50. color: #82ccf3;
  51. }
  52. .item {
  53. width: 100%;
  54. align-items: center;
  55. justify-content: center;
  56. display: flex;
  57. flex-direction: row;
  58. font-size: 18px;
  59. }
复制代码
  1. Component({
  2.   /**
  3.   * 组件的属性列表
  4.   */
  5.   properties: {
  6.     range: { //可预约的日期范围。默认日期从今天开始,到第range天后为止,这里设为10天
  7.       type: Number,
  8.       value: 10
  9.     },
  10.     start_time: { //开始时间,设为整点
  11.       type: Number,
  12.       value: 8
  13.     },
  14.     step: { //预约时间的步长,设置为30,表示30分钟
  15.       type: Number
  16.     },
  17.     end_time: { //结束时间,设为整点
  18.       type: Number,
  19.       value: 22
  20.     }
  21.   },
  22.   /**
  23.   * 组件的初始数据
  24.   */
  25.   data: {
  26.     isShow: false,
  27.     selectDate: "",
  28.     dialogh: 0,
  29.     //日期列表和时间列表
  30.     date_list: [],
  31.     time_list: []
  32.   },
  33.   attached: function () {
  34.     let start_day = this.ts_string(new Date().getTime());
  35.     console.log(start_day); //2021-08-31
  36.     console.log(new Date());
  37.     let end_day = this.ts_string(new Date().setDate(new Date().getDate() + this.properties.range))
  38.     //获取日期列表
  39.     let date_list = this.getDiffDate(start_day, end_day);
  40.     //获取时间列表
  41.     let time_list = this.getTimeList(this.properties.start_time, this.properties.end_time, this.properties.step);
  42.     console.log(time_list);
  43.     this.setData({
  44.       // date_time: [date_column, time_column],
  45.       date_list: date_list,
  46.       time_list: time_list,
  47.     })
  48.     //动画
  49.     this.animation = wx.createAnimation({
  50.       duration: 300
  51.     })
  52.     //500rpx转成px
  53.     let dialoghpx = 800 / 750 * wx.getSystemInfoSync().windowWidth
  54.     this.setData({
  55.       dialogh: dialoghpx,
  56.       selectDate: this.data.date_list[0] + this.data.time_list[0]
  57.     })
  58.   },
  59.   methods: {
  60.     getDiffDate(start, end) {
  61.       let startTime = new Date(start);
  62.       let endTime = new Date(end);
  63.       let dateArr = [];
  64.       while ((endTime.getTime() - startTime.getTime()) >= 0) {
  65.         dateArr.push(this.ts_string(startTime.getTime()));
  66.         startTime.setDate(startTime.getDate() + 1);
  67.       }
  68.       return dateArr;
  69.     },
  70.     zfill(num, length) {
  71.       return (Array(length).join('0') + num).slice(-length);
  72.     },
  73.     //把日期转换成xxxx-xx-xx的形式
  74.     ts_string(timestamp) {
  75.       let d = new Date(timestamp);
  76.       let day = "";
  77.       switch (d.getDay()) {
  78.         case 1:
  79.           day = "周一";
  80.           break;
  81.         case 2:
  82.           day = "周二";
  83.           break;
  84.         case 3:
  85.           day = "周三";
  86.           break;
  87.         case 4:
  88.           day = "周四";
  89.           break;
  90.         case 5:
  91.           day = "周五";
  92.           break;
  93.         case 6:
  94.           day = "周六";
  95.           break;
  96.         case 0:
  97.           day = "周日";
  98.           break;
  99.       }
  100.       let string = (d.getFullYear()) + "-" +
  101.         this.zfill((d.getMonth() + 1), 2) + "-" +
  102.         this.zfill((d.getDate()), 2) + " (" + day + ")"
  103.       return string
  104.     },
  105.     //获取时间区间列表,输入(起始时间,结束时间,步长)
  106.     getTimeList(start, end, step) {
  107.       let start_time = new Date();
  108.       //设置起始时间
  109.       start_time.setHours(start, 0, 0);
  110.       console.log(start_time);
  111.       //设置结束时间
  112.       let end_time = new Date();
  113.       end_time.setHours(end, 0, 0);
  114.       let startG = start_time.getTime(); //起始时间的格林时间
  115.       let endG = end_time.getTime(); //起始时间的格林时间
  116.       let step_ms = step * 60 * 1000;
  117.       let timeArr = [];
  118.       while (startG < endG) {
  119.         let time = this.timeAdd(startG, step_ms);
  120.         timeArr.push(time);
  121.         startG += step_ms;
  122.       }
  123.       return timeArr;
  124.     },
  125.     timeAdd(time1, add) {
  126.       var nd = new Date(time1); //创建时间对象
  127.       //获取起始时间的时分秒
  128.       var hh1 = nd.getHours();
  129.       var mm1 = nd.getMinutes();
  130.       if (hh1 <= 9) hh1 = "0" + hh1;
  131.       if (mm1 <= 9) mm1 = "0" + mm1;
  132.       nd = nd.valueOf(); //转换为毫秒数
  133.       nd = nd + Number(add);
  134.       nd = new Date(nd);
  135.       var hh2 = nd.getHours();
  136.       var mm2 = nd.getMinutes();
  137.       if (hh2 <= 9) hh2 = "0" + hh2;
  138.       if (mm2 <= 9) mm2 = "0" + mm2;
  139.       var time = hh1 + ":" + mm1 + "-" + hh2 + ":" + mm2;
  140.       return time; //时间段
  141.     },
  142.     change: function (e) {
  143.       const val = e.detail.value;
  144.       //val[0]表示选择的第一列序号,val[1]表示选择的第二列序号
  145.       let select = this.data.date_list[val[0]] + this.data.time_list[val[1]]
  146.       console.log(select);
  147.       this.setData({
  148.         selectDate: select
  149.       })
  150.     },
  151.     showDialog() {
  152.       this.setData({
  153.         isShow: true
  154.       })
  155.       //先向下移动dialog高度,然后恢复原位从而形成从下向上弹出效果
  156.       this.animation.translateY(this.data.dialogh).translateY(0).step()
  157.       this.setData({
  158.         animation: this.animation.export()
  159.       })
  160.     },
  161.     dimsss() {
  162.       //从原位向下移动dailog高度,形成从上向下的收起效果
  163.       this.animation.translateY(this.data.dialogh).step()
  164.       this.setData({
  165.         animation: this.animation.export()
  166.       })
  167.       //动画结束后蒙层消失
  168.       setTimeout(() => {
  169.         this.setData({
  170.           isShow: false
  171.         })
  172.       }, 300)
  173.     },
  174.     cancel() {
  175.       this.triggerEvent("cancel")
  176.       this.dimsss()
  177.     },
  178.     confirm() {
  179.       this.triggerEvent("confirm", {
  180.         selectDate: this.data.selectDate
  181.       })
  182.       this.dimsss()
  183.     }
  184.   }
  185. })
复制代码
组件的使用
想在父组件中使用封装好的date-picker组件,先要在父组件的json文件中声明。
  1. {
  2. "usingComponents": {
  3.   "date-picker": "../../components/date-picker/date-picker"
  4. },
  5. }
复制代码
如果想实现简单的选择时间段并在页面中显示的功能,父组件代码如下编写即可。
父组件wxml文件:
  1. <view class="option" bindtap="timeOpen" style="font-size: 16px;">
  2.    {{selectDate}}
  3. </view>
  4. <date-picker id="picker" range="8" step="40" bindconfirm="confirm"></date-picker>
复制代码
父组件js文件:
  1. Page({
  2.   data: {
  3.     selectDate: "",
  4.     machineShow: false,
  5.   },
  6.   onLoad: function () {
  7.     this.picker = this.selectComponent("#picker")
  8.   },
  9.   timeOpen() {
  10.     this.picker.showDialog();
  11.   },
  12.   confirm(e)
  13.     this.setData({
  14.       selectDate: e.detail.selectDate
  15.     })
  16.   },
  17. })
复制代码
2.结合vant weapp的date-picker
自定义定义的date-picker组件已经可以实现想实现的功能,但自定义的组件样式不够美观。这时,我注意到了小程序可以使用vant的组件库,组件库多列选择器的样式可以自由修改,而且自带样式已经足够美观,所以下面考虑结合vant组件库实现date-picker。
实现效果


具体实现
使用vant weapp的picker组件和popup组件可以更简洁地实现想要的效果,打造自定义的date-picker组件。
首先需要在编写组件的json文件中导入vant weapp的相应组件
  1. {
  2.   "component": true,
  3.   "usingComponents": {
  4.     "van-picker": "@vant/weapp/picker/index",
  5.     "van-popup": "@vant/weapp/popup/index"
  6.   }
  7. }
复制代码
然后编写date-picker的wxml文件:
  1. <van-popup round show="{{ isShow }}" bind:close="cancel" position="bottom" custom-style="height: 55%">
  2. <van-picker show-toolbar columns="{{ date_time_list }}" bind:cancel="cancel" bind:change="change"
  3.   bind:confirm="confirm" />
  4. </van-popup>
复制代码
因为van-picker的参数columns接受的是一个对象数组,与picker-view有一定差异,所以需要将date-picker的js文件进行如下更改。
1.修改data,增加date_time_list
  1. data: {
  2.     isShow: false,
  3.     selectDate: "",
  4.     dialogh: 0,
  5.     //日期列表和时间列表
  6.     date_list: [],
  7.     time_list: [],
  8.     date_time_list: [] //增加的字段
  9.   },
复制代码
2.修改attached函数
  1. //增加的内容
  2. let date_time_list = [{
  3.         values: date_list
  4.       },
  5.       {
  6.         values: time_list
  7.       }
  8.     ];
  9.     this.setData({
  10.       date_list: date_list,
  11.       time_list: time_list,
  12.       date_time_list: date_time_list //增加的内容
  13.     })
复制代码
3.修改change函数
  1. change: function (e) {
  2.       let val = e.detail.value;
  3.       let select = val[0] + val[1];
  4.       this.setData({
  5.         selectDate: select
  6.       })
  7.     },
复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持中国红客联盟。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2025 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行