资讯专栏INFORMATION COLUMN

微信小程序日期选择器使用实例

3403771864 / 33人阅读

  需求:在小程序开发中,时常会遇到日期选择器、时间选择器或者地区选择器来进行选择的功能。这是可以形成模板,只是在其中有细微变化,比如:样式会多样化、功能会复杂化。现在我们写一个合适的组件。

  下面跟大家分享下我写的一个自定义日期选择器组件

  首先上效果图看看:

  主要步骤:

  第一步:首先自定义选择器组件需要用到picker-view跟picker-view-column。使用方法如下~

  <picker-view indicator-class="picker-indicator" value="{{pickerIndexList}}" bindchange="bindChangeDate">
  <picker-view-column>
  <view wx:for="{{yearList}}" wx:key="index" class="{{pickerIndexList[0]==index?'txt-active':''}}">{{item}}年</view>
  </picker-view-column>
  <picker-view-column>
  <view wx:for="{{monthList}}" wx:key="index" class="{{pickerIndexList[1]==index?'txt-active':''}}">{{item}}月</view>
  </picker-view-column>
  <picker-view-column>
  <view wx:for="{{dayList}}" wx:key="index" class="{{pickerIndexList[2]==index?'txt-active':''}}">{{item}}日</view>
  </picker-view-column>
  </picker-view>

  第二步:打开选择器时就要获取到当前的年月日,我这里使用了for遍历直接生成年份数组跟月份数组。注:天数根据年份跟月份动态生成

  //獲取當前日期
  getCurrentDate: function (e) {
  var that = this;
  var yearList = [], monthList = [], dayList = [];
  for (var i = new Date().getFullYear(); i <= 2050; i++) {//年份
  yearList.push(i);
  }
  for (var i = 1; i <= 12; i++) {//月份
  monthList.push(i);
  }
  var myDate = new Date();
  var currentYearIndex = yearList.findIndex(o => o == myDate.getFullYear());
  var currentMonthIndex = monthList.findIndex(o => o == myDate.getMonth() + 1);
  var dayList = that.getDayList(currentYearIndex, currentMonthIndex);//天
  var currentDayIndex = dayList.findIndex(o => o == myDate.getDate());
  var pickerIndexList = that.data.pickerIndexList;
  pickerIndexList[0] = currentYearIndex;
  pickerIndexList[1] = currentMonthIndex;
  pickerIndexList[2] = currentDayIndex;
  app.globalData.dateIndexList = pickerIndexList;
  that.setData({
  yearList,
  monthList,
  dayList,
  })
  },

  第三步:在选择的过程中,选择器有个改变事件,当年份或者月份改变的时候,天数要随之变化

  //日期选择改变事件
  bindChangeDate: function (e) {
  var that = this;
  var pickerColumnList = e.detail.value;
  that.setData({
  dayList: that.getDayList(pickerColumnList[0], pickerColumnList[1]),
  pickerIndexList: pickerColumnList,
  })
  },

  有个样式的小问题:如选中行背景色写在picker-view控件中,则会出现滚动时背景色也会随着动,体验不好。所以我这里写了一个占位符,设置背景色,滚动选择时背景色就不会受到影响

  <!-- 选中行背景色 start-->
  <view class="top-background">
  <view></view>
  <view></view>
  <view></view>
  </view>
  <!-- 选中行背景色 end-->

  下面是全部代码~~

  wxml:

  <!-- 自定义选择日期层 start -->
  <view class="date-layer" wx:if="{{isShowDateLayer}}" catchtouchmove="catchTouchMove">
  <view class="layer-box">
  <view class="box-top">
  <!-- 选中行背景色 start-->
  <view class="top-background">
  <view></view>
  <view></view>
  <view></view>
  </view>
  <!-- 选中行背景色 end-->
  <picker-view indicator-class="picker-indicator" value="{{pickerIndexList}}" bindchange="bindChangeDate">
  <picker-view-column>
  <view wx:for="{{yearList}}" wx:key="index" class="{{pickerIndexList[0]==index?'txt-active':''}}">{{item}}年</view>
  </picker-view-column>
  <picker-view-column>
  <view wx:for="{{monthList}}" wx:key="index" class="{{pickerIndexList[1]==index?'txt-active':''}}">{{item}}月</view>
  </picker-view-column>
  <picker-view-column>
  <view wx:for="{{dayList}}" wx:key="index" class="{{pickerIndexList[2]==index?'txt-active':''}}">{{item}}日</view>
  </picker-view-column>
  </picker-view>
  </view>
  <view class="box-bottom">
  <button class="btn-confirm" bindtap="bindConfirmDate">確定</button>
  <button class="btn-cancel" bindtap="bindCancelDate">取消</button>
  </view>
  </view>
  </view>
  <!-- 选择日期层 end -->

  js:

  /**
  *页面的初始数据
  */
  data:{
  pickerIndexList:[0,0,0],//日期选择器下标
  isShowDateLayer:false,//是否显示日期弹层
  txtDate:'請选择提貨日期',//选中日期
  isSeltDate:false,//是否选择日期
  },
  //截获竖向滑动
  catchTouchMove:function(res){
  return true;
  },
  //获取天数列表
  getDayList:function(year,month){
  var that=this;
  var dayList;
  switch(month+1){
  case 1:
  case 3:
  case 5:
  case 7:
  case 8:
  case 10:
  case 12:dayList=that.getDayNum(31);
  break;
  case 4:
  case 6:
  case 9:
  case 11:dayList=that.getDayNum(30);
  break;
  case 2:dayList=that.getDayNum((that.data.yearList[year]%4==0&&that.data.yearList[year]%100!=0||that.data.yearList[year]%400==0)?29:28);
  break;
  }
  return dayList;
  },
  //获取天数
  getDayNum:function(num){
  var dayList=[];
  for(var i=1;i&lt;=num;i++){
  dayList.push(i);
  }
  return dayList;
  },
  //打开选择日期弹层
  bindOpenDateLayer:function(e){
  var that=this;
  var pickerIndexList=that.data.pickerIndexList;
  that.setData({
  isShowDateLayer:!that.data.isShowDateLayer,
  dayList:that.getDayList(pickerIndexList[0],pickerIndexList[1]),
  })
  },
  //日期选择改变事件
  bindChangeDate:function(e){
  var that=this;
  var pickerColumnList=e.detail.value;
  that.setData({
  dayList:that.getDayList(pickerColumnList[0],pickerColumnList[1]),
  pickerIndexList:pickerColumnList,
  })
  },
  //选择日期弹层确定按钮
  bindConfirmDate:function(e){
  var that=this;
  var pickerIndexList=that.data.pickerIndexList;
  var txtDate=that.data.yearList[pickerIndexList[0]]+'-'+that.data.monthList[pickerIndexList[1]]+'-'+that.data.dayList[pickerIndexList[2]];
  that.setData({
  isShowDateLayer:false,
  pickerIndexList,
  txtDate,
  isSeltDate:true,
  })
  },
  //选择日期弹层取消按钮
  bindCancelDate:function(e){
  var that=this;
  var pickerIndexList=that.data.pickerIndexList;
  that.setData({
  isShowDateLayer:!that.data.isShowDateLayer,
  })
  var yearList=that.data.yearList;
  var monthList=that.data.monthList;
  var txtDate=that.data.txtDate;
  var yearIndex=yearList.findIndex(o=&gt;o==parseInt(txtDate.slice(0,txtDate.indexOf('-'))));//年份下标
  var monthIndex=monthList.findIndex(o=&gt;o==parseInt(txtDate.slice(txtDate.indexOf('-')+1,txtDate.lastIndexOf('-'))));//月份下标
  var dayList=that.getDayList(yearIndex,monthIndex);//天数
  if(that.data.isSeltDate){//选择过日期
  if(txtDate==(yearList[pickerIndexList[0]]+'-'+monthList[pickerIndexList[1]]+'-'+dayList[pickerIndexList[2]]))
  that.setData({pickerIndexList})
  else
  that.setData({pickerIndexList:[yearIndex,monthIndex,dayList.findIndex(o=&gt;o==parseInt(txtDate.slice(txtDate.lastIndexOf('-')+1,txtDate.length)))]})
  }else{//未选择过日期
  that.setData({
  pickerIndexList:app.globalData.dateIndexList,
  })
  }
  },
  //阻止冒泡事件
  catchLayer:function(e){},
  //獲取當前日期
  getCurrentDate:function(e){
  var that=this;
  var yearList=[],monthList=[],dayList=[];
  for(var i=new Date().getFullYear();i&lt;=2050;i++){//年份
  yearList.push(i);
  }
  for(var i=1;i&lt;=12;i++){//月份
  monthList.push(i);
  }
  var myDate=new Date();
  var currentYearIndex=yearList.findIndex(o=&gt;o==myDate.getFullYear());
  var currentMonthIndex=monthList.findIndex(o=&gt;o==myDate.getMonth()+1);
  var dayList=that.getDayList(currentYearIndex,currentMonthIndex);//天
  var currentDayIndex=dayList.findIndex(o=&gt;o==myDate.getDate());
  var pickerIndexList=that.data.pickerIndexList;
  pickerIndexList[0]=currentYearIndex;
  pickerIndexList[1]=currentMonthIndex;
  pickerIndexList[2]=currentDayIndex;
  app.globalData.dateIndexList=pickerIndexList;
  that.setData({
  yearList,
  monthList,
  dayList,
  })
  },
  /**
  *生命周期函数--监听页面加载
  */
  onLoad:function(options){
  var that=this;
  that.getCurrentDate();//獲取當前時間
  that.setData({
  pickerIndexList:that.data.pickerIndexList
  })
  },

  wxss:

 

 /* 日期选择弹框 start */
  .main .date-layer {
  height: 100%;
  width: 100%;
  background: rgba(0, 0, 0, 0.65);
  position: fixed;
  top: 0;
  z-index: 20;
  }
  .date-layer .layer-box {
  position: fixed;
  bottom: 0;
  width: 100%;
  background: #fff;
  border-top-left-radius: 24rpx;
  border-top-right-radius: 24rpx;
  }
  .date-layer .layer-box .box-top {
  padding: 30rpx 0;
  position: relative;
  }
  .date-layer .layer-box picker-view {
  height: 120px;
  width: 88%;
  margin: 0 auto;
  }
  .date-layer .layer-box .picker-indicator {
  height: 40px;
  line-height: 40px;
  }
  .date-layer .layer-box picker-view-column view {
  line-height: 42px;
  text-align: center;
  width: 96%;
  margin: 0 auto;
  }
  .date-layer .layer-box .box-top .top-background {
  height: 80rpx;
  width: 88%;
  margin: 0 auto;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  }
  .layer-box .box-top .top-background view {
  height: 100%;
  width: 96%;
  margin: 0 auto;
  background: rgba(195, 218, 49, 0.12);
  border-top: 2rpx solid #D9E87D;
  border-bottom: 2rpx solid #C3DA31;
  margin: 0 4rpx;
  box-sizing: border-box;
  }
  .date-layer .layer-box .box-bottom {
  display: flex;
  }
  .date-layer .layer-box .box-bottom button {
  margin: 0;
  padding: 0;
  width: 50%;
  border-radius: 0;
  border: none;
  background: #fff;
  height: 100rpx;
  line-height: 100rpx;
  font-size: 34rpx;
  border-top: 2rpx solid #D8D8D8;
  }
  .date-layer .layer-box .box-bottom .btn-confirm {
  border-right: 1rpx solid #D8D8D8;
  color: #C3DA31;
  }
  .date-layer .layer-box .box-bottom .btn-cancel {
  border-left: 1rpx solid #D8D8D8;
  color: #B1B1B4;
  }
  /* 日期选择弹框 end */

  以上就是全部内容,开始自己设计一个吧。


文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/128376.html

相关文章

  • 如何写一个信小程序组件

    背景 先谈下背景,在做一款产品的时候需要用到日期选择,但是官方的却不太满足需求,因为无法选择农历啊。所以自己来造一个轮子好了,造轮子之前先想想啊,万一以后多个地方要用到,多个项目要用,怎么办呢? 那...

    lijinke666 评论0 收藏0
  • 信小程序里碰到的坑和小知识

    ...g 2.未解决用小程序自带的底部导航组件的话, 没法实现跟微信原生底部小红点或者消息提醒的功能 3.已解决picker使用时候 picker组件里必须要有内容,放一个值为空的变量并没有作用 这里我如果只保留{{age}}的话, 这个组件是无法触...

    yagami 评论0 收藏0
  • 信小程序里碰到的坑和小知识

    ...g 2.未解决用小程序自带的底部导航组件的话, 没法实现跟微信原生底部小红点或者消息提醒的功能 3.已解决picker使用时候 picker组件里必须要有内容,放一个值为空的变量并没有作用 这里我如果只保留{{age}}的话, 这个组件是无法触...

    animabear 评论0 收藏0
  • 信小程序里碰到的坑和小知识

    ...g 2.未解决用小程序自带的底部导航组件的话, 没法实现跟微信原生底部小红点或者消息提醒的功能 3.已解决picker使用时候 picker组件里必须要有内容,放一个值为空的变量并没有作用 这里我如果只保留{{age}}的话, 这个组件是无法触...

    233jl 评论0 收藏0
  • 信小程序picker组件遇到的问题与解决方案

    一、picker基本概念 当然先看官方文档 picker说明搞清楚基本概念“从底部弹起的滚动选择,现支持三种选择,通过mode来区分,分别是普通选择,时间选择日期选择,默认是普通选择。”几个主要属性:range: ...

    tulayang 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<