前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >微信小程序日期+时间选择器

微信小程序日期+时间选择器

作者头像
李才哥
发布2019-07-10 16:13:54
7.4K0
发布2019-07-10 16:13:54
举报
文章被收录于专栏:李才哥
最近在做一些小程序项目,应项目需求开始学习wxml、wxss和js语法,其中有个地方需要用到选择器。在iOS中使用UIPickerView控件可以完成。同样在官方文档中也可以找到picker组件,微信小程序组件-picker

这种内置定义好的选择器都是从底部弹起。目前支持五种选择器,通过设置mode来区分。分别是普通选择器,多列选择器,时间选择器,日期选择器,省市区选择器,默认是普通选择器。

先贴上需求效果:

这里我使用多列选择器,普通选择器、日期选择器和时间选择器没法实现。

首先定义在wxml中定义picker组件:

代码语言:javascript
复制
<picker class='time-picker' mode="multiSelector" bindchange="bindStartMultiPickerChange" bindtap='pickerTap' bindcolumnchange="bindMultiPickerColumnChange" value="{{multiIndex}}" range="{{multiArray}}">{{startDate}}</picker>

这里定义的range为一个二维数组,现在数据是写定的:

代码语言:javascript
复制
// .js
multiArray: [['今天', '明天', '3-2', '3-3', '3-4', '3-5'], [0, 1, 2, 3, 4, 5, 6], [0, 10, 20]],

很明显这里的数据并不符合要求,按照需求,这里应该是展示当前的日期格式为:月-日 时 分 其中月-日列为:今天,明天,然后往后延28天。 时这里为0~23点 24个选项 分钟这里按照0~10,10~20,20~30,30~40,40~50来分段显示!

修改js代码:

代码语言:javascript
复制
pickerTap:function() {
    var date = new Date();

    var monthDay = ['今天','明天'];
    var hours = [];
    var minute = [];

    // 月-日
    for (var i = 2; i <= 28; i++) {
      var date1 = new Date(date);
      date1.setDate(date.getDate() + i);
      var md = (date1.getMonth() + 1) + "-" + date1.getDate();
      monthDay.push(md);
    }

    // 时
    for (var i = 0; i < 24; i++) {
      hours.push(i);
    }

    // 分
    for (var i = 0; i < 60; i += 10) {
      minute.push(i);
    }

    var data = {
      multiArray: this.data.multiArray,
      multiIndex: this.data.multiIndex
   };
    data.multiArray[0] = monthDay;
    data.multiArray[1] = hours;
    data.multiArray[2] = minute;
    this.setData(data);
},

在pickerTap函数中定义三个数组分别储存月-日、时、分。

然后在当前日期上往后延2-28天,并分别push到monthDay数组中。时和分比较好添加。添加完毕最后赋值给multiArray。在编译的话月-日、时、分总算完整了。

但是发现选择今天的时候,时、分是可以在0~23、0~50之间选择的。如果现在是上午9点,我们在选择今天的时间候就只能选择9点以后的了。所以这里需要改进一下。如果选择今天,那么时、分中只能是当前时间往后的选项。

这里还有一点需要注意,如果今天时间是9:55。那么选项中首条应该怎么展示。首先时这里应该是10点往后延,而分就是0~50了。所以在获取到当前分还需要做判断才能给hours和minute赋值,具体看一下代码:

代码语言:javascript
复制
var currentHours = date.getHours();
    var currentMinute = date.getMinutes();

    // 月-日
    for (var i = 2; i <= 28; i++) {
      var date1 = new Date(date);
      date1.setDate(date.getDate() + i);
      var md = (date1.getMonth() + 1) + "-" + date1.getDate();
      monthDay.push(md);
    }

    var minuteIndex;
    if (currentMinute > 0 && currentMinute <= 10) {
      minuteIndex = 10;
    } else if (currentMinute > 10 && currentMinute <= 20) {
      minuteIndex = 20;
    } else if (currentMinute > 20 && currentMinute <= 30) {
      minuteIndex = 30;
    } else if (currentMinute > 30 && currentMinute <= 40) {
      minuteIndex = 40;
    } else if (currentMinute > 40 && currentMinute <= 50) {
      minuteIndex = 50;
    } else {
      minuteIndex = 60;
    }

    if (minuteIndex == 60) {
      // 时
      for (var i = currentHours+1; i < 24; i++) {
        hours.push(i);
      }

      // 分
      for (var i = 0; i < 60; i += 10) {
        minute.push(i);
      }

    } else {
      // 时
      for (var i = currentHours; i < 24; i++) {
        hours.push(i);
      }

      // 分
      for (var i = minuteIndex; i < 60; i += 10) {
        minute.push(i);
      }
 }

首先获取当前时分,并给分值分段。如果minuteIndex = 60,也就是当前分为50~60之间。这种情况下就是当前时+1,分为0~50。否则就是当前时~23点,当前分在那个分段~50这样显示。

虽然这样改进之后第一次点开picker展示没问题。但是在开始选择时就不行了。当时选择17,这里的分展示肯定有问题。所以这里的数据我们还需要根据每列的选择来变动。

具体需求: 当选择今天。时为当前时,那么分就展示当前分段~50选项。 当选择今天。时不为当前时,那么分就展示 0~50选项。 当第一列不为今天,那么时就为 0~23选项,分就为0~50的选项。 按照需求来代码实现:

代码语言:javascript
复制
bindMultiPickerColumnChange:function(e) {

    date = new Date();

    var that = this;

    var monthDay = ['今天', '明天'];
    var hours = [];
    var minute = [];

    currentHours = date.getHours();
    currentMinute = date.getMinutes();

    var data = {
      multiArray: this.data.multiArray,
      multiIndex: this.data.multiIndex
    };
    // 把选择的对应值赋值给 multiIndex
    data.multiIndex[e.detail.column] = e.detail.value;

    // 然后再判断当前改变的是哪一列,如果是第1列改变
    if (e.detail.column === 0) {
      // 如果第一列滚动到第一行
      if (e.detail.value === 0) {

        that.loadData(hours, minute);
        
      } else {
        that.loadHoursMinute(hours, minute);
      }

      data.multiIndex[1] = 0;
      data.multiIndex[2] = 0;

      // 如果是第2列改变
    } else if (e.detail.column === 1) {

      // 如果第一列为今天
      if (data.multiIndex[0] === 0) {
        if (e.detail.value === 0) {
          that.loadData(hours, minute);
        } else {
          that.loadMinute(hours, minute);
        }
        // 第一列不为今天
      } else {
        that.loadHoursMinute(hours, minute);
      }
      data.multiIndex[2] = 0;

      // 如果是第3列改变
    } else {
      // 如果第一列为'今天'
      if (data.multiIndex[0] === 0) {

        // 如果第一列为 '今天'并且第二列为当前时间
        if(data.multiIndex[1] === 0) {
          that.loadData(hours, minute);
        } else {
          that.loadMinute(hours, minute);
        }
      } else {
        that.loadHoursMinute(hours, minute);
      }
    }
    data.multiArray[1] = hours;
    data.multiArray[2] = minute;
    this.setData(data);
  },

  loadData: function (hours, minute) {
    var minuteIndex;
    if (currentMinute > 0 && currentMinute <= 10) {
      minuteIndex = 10;
    } else if (currentMinute > 10 && currentMinute <= 20) {
      minuteIndex = 20;
    } else if (currentMinute > 20 && currentMinute <= 30) {
      minuteIndex = 30;
    } else if (currentMinute > 30 && currentMinute <= 40) {
      minuteIndex = 40;
    } else if (currentMinute > 40 && currentMinute <= 50) {
      minuteIndex = 50;
    } else {
      minuteIndex = 60;
    }

    if (minuteIndex == 60) {
      // 时
      for (var i = currentHours + 1; i < 24; i++) {
        hours.push(i);
      }
      // 分
      for (var i = 0; i < 60; i += 10) {
        minute.push(i);
      }
    } else {
      // 时
      for (var i = currentHours; i < 24; i++) {
        hours.push(i);
      }
      // 分
      for (var i = minuteIndex; i < 60; i += 10) {
        minute.push(i);
      }
    }
  },

  loadHoursMinute: function (hours, minute){
    // 时
    for (var i = 0; i < 24; i++) {
      hours.push(i);
    }
    // 分
    for (var i = 0; i < 60; i += 10) {
      minute.push(i);
    }
  },

  loadMinute: function (hours, minute) {
    var minuteIndex;
    if (currentMinute > 0 && currentMinute <= 10) {
      minuteIndex = 10;
    } else if (currentMinute > 10 && currentMinute <= 20) {
      minuteIndex = 20;
    } else if (currentMinute > 20 && currentMinute <= 30) {
      minuteIndex = 30;
    } else if (currentMinute > 30 && currentMinute <= 40) {
      minuteIndex = 40;
    } else if (currentMinute > 40 && currentMinute <= 50) {
      minuteIndex = 50;
    } else {
      minuteIndex = 60;
    }

    if (minuteIndex == 60) {
      // 时
      for (var i = currentHours + 1; i < 24; i++) {
        hours.push(i);
      }
    } else {
      // 时
      for (var i = currentHours; i < 24; i++) {
        hours.push(i);
      }
    }
    // 分
    for (var i = 0; i < 60; i += 10) {
      minute.push(i);
    }
  },

简要说明一下。picker每列数据变动事都会调bindMultiPickerColumnChange函数。首先每次拿到最新时间,并更新全局当前时、分:

代码语言:javascript
复制
date = new Date();
currentHours = date.getHours();
currentMinute = date.getMinutes();

拿到page-data里面的multiArray:元数据数组和muliIndex:picker改变数据数组:

代码语言:javascript
复制
multiArray: this.data.multiArray,
multiIndex: this.data.multiIndex

picker改动的列索引和对应的值在e.detail中,所以每次改变,就把值赋值给multiIndex:

代码语言:javascript
复制
data.multiIndex[e.detail.column] = e.detail.value;

现在开始判断了,如果第一列或第二列或第三列发生改变:

代码语言:javascript
复制
if (e.detail.column === 0) {
    // 如果第一列滚动到第一行
   if (e.detail.value === 0) {
      var minuteIndex;
    if (currentMinute > 0 && currentMinute <= 10) {
      minuteIndex = 10;
    } else if (currentMinute > 10 && currentMinute <= 20) {
      minuteIndex = 20;
    } else if (currentMinute > 20 && currentMinute <= 30) {
      minuteIndex = 30;
    } else if (currentMinute > 30 && currentMinute <= 40) {
      minuteIndex = 40;
    } else if (currentMinute > 40 && currentMinute <= 50) {
      minuteIndex = 50;
    } else {
      minuteIndex = 60;
    }

    if (minuteIndex == 60) {
      // 时
      for (var i = currentHours + 1; i < 24; i++) {
        hours.push(i);
      }
      // 分
      for (var i = 0; i < 60; i += 10) {
        minute.push(i);
      }
    } else {
      // 时
      for (var i = currentHours; i < 24; i++) {
        hours.push(i);
      }
      // 分
      for (var i = minuteIndex; i < 60; i += 10) {
        minute.push(i);
      }
    }
 } else {
      // 时
    for (var i = 0; i < 24; i++) {
      hours.push(i);
    }
    // 分
    for (var i = 0; i < 60; i += 10) {
      minute.push(i);
    }
 }
    data.multiIndex[1] = 0;
    data.multiIndex[2] = 0;
}

如果是第一列发生改变,并且是滚动到0,也就是滚动到 '今天' 的时候,第二列和第三列对应的应该变为当前时和分来显示。这里的minuteIndex定义为局部变量,是把当前分划分到哪个时间段的。如果在0~10之内,那么分钟显示为10、20、30、40、50。如果在40~50之间的话,分钟应该显示为50。如果分钟在50~60之间的话,这个时候小时应该+1,并且分钟为0、10、20、30、40、50。

如果当前为18:54,那么显示应该如下:

上面是对第一列为 '今天的操作',如果第一列不为今天,那么第二列和第三列就应该显示全部数据。也就是下面这段代码:

代码语言:javascript
复制
 // 时
for (var i = 0; i < 24; i++) {
    hours.push(i);
}
    // 分
for (var i = 0; i < 60; i += 10) {
    minute.push(i);
}

给hours和minute赋值之后,最后再赋值给multiArray就可以显示出来了。 最后一一步就是在第一列改变的时候,第二列和第三列相应都滚动到0号位。

代码语言:javascript
复制
data.multiIndex[1] = 0;
data.multiIndex[2] = 0;

接下来是第二列改变的判断:

代码语言:javascript
复制
else if (e.detail.column === 1) {
    // 如果第一列为今天
  if (data.multiIndex[0] === 0) {
  if (e.detail.value === 0) {
      var minuteIndex;
    if (currentMinute > 0 && currentMinute <= 10) {
      minuteIndex = 10;
    } else if (currentMinute > 10 && currentMinute <= 20) {
      minuteIndex = 20;
    } else if (currentMinute > 20 && currentMinute <= 30) {
      minuteIndex = 30;
    } else if (currentMinute > 30 && currentMinute <= 40) {
      minuteIndex = 40;
    } else if (currentMinute > 40 && currentMinute <= 50) {
      minuteIndex = 50;
    } else {
      minuteIndex = 60;
    }

    if (minuteIndex == 60) {
      // 时
      for (var i = currentHours + 1; i < 24; i++) {
        hours.push(i);
      }
      // 分
      for (var i = 0; i < 60; i += 10) {
        minute.push(i);
      }
    } else {
      // 时
      for (var i = currentHours; i < 24; i++) {
        hours.push(i);
      }
      // 分
      for (var i = minuteIndex; i < 60; i += 10) {
        minute.push(i);
      }
    }
  } else {
      var minuteIndex;
    if (currentMinute > 0 && currentMinute <= 10) {
      minuteIndex = 10;
    } else if (currentMinute > 10 && currentMinute <= 20) {
      minuteIndex = 20;
    } else if (currentMinute > 20 && currentMinute <= 30) {
      minuteIndex = 30;
    } else if (currentMinute > 30 && currentMinute <= 40) {
      minuteIndex = 40;
    } else if (currentMinute > 40 && currentMinute <= 50) {
      minuteIndex = 50;
    } else {
      minuteIndex = 60;
    }

    if (minuteIndex == 60) {
      // 时
      for (var i = currentHours + 1; i < 24; i++) {
        hours.push(i);
      }
    } else {
      // 时
      for (var i = currentHours; i < 24; i++) {
        hours.push(i);
      }
    }
    // 分
    for (var i = 0; i < 60; i += 10) {
      minute.push(i);
    }
    }
      // 第一列不为今天
   } else {
     // 时
    for (var i = 0; i < 24; i++) {
      hours.push(i);
    }
    // 分
    for (var i = 0; i < 60; i += 10) {
      minute.push(i);
    }
   }
    data.multiIndex[2] = 0;
}

如果第二列发生改变,要根据第一列的位置来改变hours和minute的值。所以如果第一列为0,也就是'今天',并且第二列也为0,那么第二列和第三列应该根据当前时间进行显示。如果第二列不为0。那么第二列根据当前时来显示,但是第三列应该是0~50全部显示。如果第一列不为'今天'。这个时候第二列和第三列都应该全部显示,也就是0~23、0~50。最后需要滚动第三列到0号位:

代码语言:javascript
复制
data.multiIndex[2] = 0;

同样如果第三列发生改变,也要根据第一列和第二列的位置来显示。如果第一列为0,第二列为0,那么这里的hours和minute应该根据当前时间来显示。如果第二列不为0,那么minute应该是0~50显示全部选项。最后如果第一列也不为0,那么hours和minute都应该全部显示。

最后把hours和minute赋值到data:

代码语言:javascript
复制
data.multiArray[1] = hours;
data.multiArray[2] = minute;
this.setData(data);

写到这里,最后的效果就如开头展示的那样。

第一次写小程序文章,如果有错误或者讲得不到位的地位欢迎留言讨论,谢谢。

最后补充一下,如果currentHours或currentHours+1 大于等于24的话要进行判断处理。

https://developers.weixin.qq.com/miniprogram/dev/component/picker-view.html

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-03-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 李才哥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档