mpvue中使用小程序原生picker实现时间日期选择(完整可用)(附坑)

最近使用mpvue开发小程序需要一个日期时间的选择器,但是小程序官方的picker控件时间和日期是分开的,在查了很多资料后发现可以使用多列选择器来实现,但是由于找到的大多数都是原生小程序的,mpvue的多列选择器只发现了一个选择省份的以及时间日期选择但是不能判断大小月以及平年闰年的2月,所以自己动手写了一个并将代码附上代码和大家分享一下。



代码如下:
1、布局部分 :
其中picker选择的mode为多列选择器
range绑定的是一个大数组中包含若干个小数组(即有年、月、日、时、分、秒则是6个小数组);value绑定的是一个数组,决定range中每一列(即每个小数组默认显示第几个);
startTime则表示的是最后显示的结果,是在后面的函数中拼凑而成的字符串;

<picker mode="multiSelector" :value="dateTimeIndex1" @change="changeDateTime1" @columnchange="changeDateTimeColumn1" :range="dateTimeArray1">
       <view class="tui-picker-detail">
             起始:{{startTime}}
       </view>
 </picker> 

2、js部分

<script>
 import Vue from 'vue' 
 
 //下面初始化中需要用到查询当前日期
const date = new Date();
//先用这些数组存储对应的年月日时分秒
const years = [];
const months = [];
const days = [];
const hours = [];
const minutes = [];
const seconds = [];

 export default {
  data() {
    return {
    //range中引入的数组,即所有的数据
      dateTimeArray1:[years,months,days,hours,minutes,seconds],
     //value中引入的数组,比如3则对应着年的列首先显示第三个数据
      dateTimeIndex1:[3, 9, 16, 10, 17,30],
      //下面用于年的函数中
      year:'2020',
      //下面用于年的判断中是否为2月进行修改
      month:'',
      //先给一个默认的日期时间
      startTime:'2020-04-06 12:30:30',
    }
  },
  onLoad(options) {
  //在onload时就调用initData函数初始化数据
    this.initData();
  }, 
  
  methods: {
  //当点下选择器的确定按钮时会触发
    changeDateTime1: function(e) {
     console.log('picker发送选择改变,携带值为',e.mp.detail.value);
    //将事件中的value给index数组,即把每一略所选的数据给index数组
     this.dateTimeIndex1 = e.mp.detail.value;
     //通过每一列选中的数据拼凑出startTime即为最终结果
     this.startTime = this.dateTimeArray1[0][this.dateTimeIndex1[0]]+'-'+this.dateTimeArray1[1][this.dateTimeIndex1[1]]+'-'+this.dateTimeArray1[2][this.dateTimeIndex1[2]]+' '+this.dateTimeArray1[3][this.dateTimeIndex1[3]]
                      +':'+this.dateTimeArray1[4][this.dateTimeIndex1[4]]+':'+this.dateTimeArray1[5][this.dateTimeIndex1[5]]
    },
     
    //该函数在每次滑动任意一列时触发
    changeDateTimeColumn1: function(e) {
     console.log('picker发送选择改变,携带值为col',e.mp.detail.column,e.mp.detail.value)
     //num用来存储选择的月数,虽然这里得到的不一定是月数,但是后面会作判断
     let num = e.mp.detail.value;
     //用来存储将要更新的数据作为过渡
     let temp = [];
     //将index对应的值设置为选中后的值,注意这个语句使用必须在上面把vue给import进来
     Vue.set(this.dateTimeIndex1,e.mp.detail.column,e.mp.detail.value)
     //如果移动的是第0列,即滑动了年的那一列
     if(e.mp.detail.column == 0){
       //如果选中的是2月则需要进行重新赋值
       if(this.month == 1){
       //获取滑到的是什么年
        this.year = this.dateTimeArray1[e.mp.detail.column][e.mp.detail.value]
        console.log("打印年份",this.year)
        //判断如果是闰年则往temp中写29天赋给array中的月数
        if((this.year % 400 == 0) || ((this.year % 100 != 0) && (this.year % 4 == 0))){
           console.log('闰年修改了年份')
           for (let i = 1; i <= 29; i++) {
                if (i < 10) {
                  i = "0" + i;
                }
                temp.push("" + i);
              }
              //并把temp中的天数赋给array中相应的位置
              Vue.set(this.dateTimeArray1,2,temp) 
        }else{
        //如果是平年同理
           console.log('平年修改了年份')
              for (let i = 1; i <= 28; i++) {
                if (i < 10) {
                  i = "0" + i;
                }
                temp.push("" + i);
              }
              Vue.set(this.dateTimeArray1,2,temp)
        }
        }
     }
     //如果改变的是月数
     if(e.mp.detail.column == 1){
     //把选中的月份赋值进来
     this.month = e.mp.detail.value;
       //如果是大月(注意数组是从0开始的),给其赋31天
        if(num == 0 || num == 2 || num == 4 || num == 6 || num == 7 || num == 9 || num == 11 ){
          console.log("单数月31天")
          for(let i=1;i<=31;i++){
             if(i<10){
               i = "0" + i;
             }
             temp.push("" + i); 
          }
          console.log('打印大月temp数组',temp)
          Vue.set(this.dateTimeArray1,2,temp)
          console.log("打印大月temp数组",this.dateTimeArray1[2])   
        }
        //如果是小月则赋30天
      else if(num == 3 || num == 5 || num == 8 || num == 10){
          for (let i = 1; i <= 30; i++) {
          if (i < 10) {
            i = "0" + i;
          }
          temp.push("" + i);
        }
        console.log("打印小月temp数组",temp)
        Vue.set(this.dateTimeArray1,2,temp)
        console.log('打印小月赋值后数组',this.dateTimeArray1[2])
        }
        //最后处理2月份的
        else if(num == 1){
          console.log('进入2月的判断')
          if(((this.year % 400 == 0) || (this.year % 100 != 0)) && (this.year % 4 == 0)){
              console.log('进入2月的闰年中')
              for (let i = 1; i <= 29; i++) {
                if (i < 10) {
                  i = "0" + i;
                }
                temp.push("" + i);
              }
              Vue.set(this.dateTimeArray1,2,temp) 
          }else{
            console.log('进入2月的平年中')
              for (let i = 1; i <= 28; i++) {
                if (i < 10) {
                  i = "0" + i;
                }
                temp.push("" + i);
              }
              Vue.set(this.dateTimeArray1,2,temp)
          }
        }
     } 
    },
    
   
    //初始化array数组,这里获取到的天数是不正确的(不能区分大小月以及2月),所以上面的column函数处理的是这个问题
    initData(){
      //获取年
      for (let i = 2017; i <= date.getFullYear() + 5; i++) {
        years.push("" + i);
      }
      console.log('打印年数组',years)
      //获取月份
      for (let i = 1; i <= 12; i++) {
        if (i < 10) {
          i = "0" + i;
        }
        months.push("" + i);
      }
      //获取日期
      for (let i = 1; i <= 31; i++) {
        if (i < 10) {
          i = "0" + i;
        }
        days.push("" + i);
      }
      //获取小时
      for (let i = 0; i < 24; i++) {
        if (i < 10) {
          i = "0" + i;
        }
        hours.push("" + i);
      }
      //获取分钟
      for (let i = 0; i < 60; i++) {
        if (i < 10) {
          i = "0" + i;
        }
        minutes.push("" + i);
      }
      //获取秒钟
      for(let i = 0; i<60; i++){
        if(i < 10){
          i = '0' + i;
        }
        seconds.push(''+i)
      }
      console.log("打印总数组",this.dateTimeArray1[0][0])  
    }


  }
}
</script>



在css中加入文字颜色以及居中等样式后效果如下图所示:
在这里插入图片描述
在这里插入图片描述

最后附上卡了好久的一个坑,在vue中使用常见的赋值语句不能检测数据的变化导致虽然给array赋了值但是选择器中看到的天数还是31天,这里再看了下面这篇博文:https://zhuimengzhu.com/content/article/id/315.html找到了解决方法,将赋值语句改为了上面代码中的vue.set解决了问题。


最后代码经过本人亲测可用,如果有什么不足之处或者不明白的地方也欢迎大家指出谢谢!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值