微信小程序的年月日年月日选择器基于picker的mode = multiSelector

微信小程序的双时间选择器基于picker的mode = multiSelector

废了好大的劲写了这么一个组件,叉会腰~
其实这段代码并不精炼,不过本人也是个刚工作一年多的小菜鸟,就先放在这里,有想法再来改;
事实上我就在写这篇博文的时候,就修改了3个bug,就当给大家提供一个思路吧;

想到啥写啥,我觉得这么写比用picker-view的好处就是可以使用原生组件,只需要管自己想管的逻辑,不过写完发现逻辑部分好鸡儿多;
我认为这个组件主要的缺点在于每次滚动事件都重新计算年月日,如果能一次计算清楚年月日,只管显示,想必会简单不少,不过本人简单想了想没找到思路,就留待大神们解决啦;

由于我用的mpx框架,这段代码不能直接插入到原生小程序里,需要修改

html部分:

			<picker 
                mode="multiSelector" 
                bindchange="bindMultiPickerChange" 
                bindcolumnchange="bindMultiPickerColumnChange" 
                value="{{multiIndex}}" 
                range="{{multiArray}}"
            >
                时间
            </picker>

js部分:

<script>
		//再次说明本人使用的是mpx框架,这段代码不能直接插入到小程序里,需要修改
		//onLoad和onShow都没反应,就写到了这里
	    const date = new Date();
	    const years = [];
	    const months = [];
	    const days = [];
	    const years2 = [];
	    const months2 = [];
	    const days2 = [];
	    const yearIndex = date.getFullYear()-2010
	    const monthIndex = date.getMonth()
	    const dayIndex = date.getDate() - 1 
	    //获取年 i是起始年份, i<=结束年份(当前年份+5)
	    for (let i = 2010; i <= date.getFullYear() + 5 ; i++) {
	        years.push("" + i);
	    }
	    //获取月份
	    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 = date.getFullYear(); i <= date.getFullYear() + 5 ; i++) {
	        years2.push("" + i);
	    }
	    //获取第二行月份
	    for (let i = date.getMonth()+1; i <= 12; i++) {
	        if (i < 10) {
	            i = "0" + i;
	        }
	        months2.push("" + i);
	    }
	    //获取第二行日期
	    for (let i = date.getDate(); i <= 31; i++) {
	        if (i < 10) {
	            i = "0" + i;
	        }
	        days2.push("" + i);
	    }
	createComponent({
		data:{
            time: '',
            multiArray: [years, months, days,"-", years2, months2, days2],
            multiIndex: [yearIndex,monthIndex , dayIndex,0, 0, 0,0],
        },
        methods: {
			bindMultiPickerChange(e) {
                // console.log('picker发送选择改变,携带值为', e.detail.value)
                this.multiIndex = e.detail.value
                const index = this.multiIndex
                const year = this.multiArray[0][index[0]]
                const month = this.multiArray[1][index[1]]
                const day = this.multiArray[2][index[2]]
                const year2 = this.multiArray[4][index[4]]
                const month2 = this.multiArray[5][index[5]]
                const day2 = this.multiArray[6][index[6]]
                this.time = year + '-' + month + '-' + day + ' 至 ' + year2 + '-' + month2 + '-' + day2 
                console.log(this.time)
                this.triggerE()
            },
            //监听picker的滚动事件, TUDO 这个组件可能还有bug,需要测试大哥的努力了 
            bindMultiPickerColumnChange(e) {
                //获取年份
                const column = e.detail.column
                const array = this.multiArray  //例 array[0][index[0]] 代表开始年份的值 array[0]代表开始年份列表
                const index = this.multiIndex   // index[0] 代表开始年份的下标
                this.multiIndex[column] = e.detail.value
                // console.log('修改的列为',column, ',值为', e.detail.value);
                if(column == 0){
                    //修改开始年份需要同步更新结束年份列表,为了不出现显示bug,还得同步更新点开始日期列表
                    this.multiArray[2] = this.getday(1,array[1][index[1]],array[0][index[0]])
                    this.multiArray[4] = this.getyear(array[0][index[0]])
                    if(array[4].length<=index[4]){//如果结束年份列表长度不足,显示列表头
                        this.multiIndex[4] = 0
                    }
                    if(array[1][index[1]] == array[5][index[5]]){  //如果月份相同,同步结束日期列表
                        this.multiArray[6] = this.getday(index[2]+1,array[5][index[5]],array[4][index[4]])
                    }
                }else if(column == 4){
                    //修改结束年份需要修改 结束日期列表 和 结束月份列表,如果 开始年份和结束年份 一致,开始月份不能小于结束月份,
                    if(array[0][index[0]] == array[4][index[4]] && array[1][index[1]] > array[5][index[5]]){
                        this.multiArray[5] = this.getmonth(index[1]+1)
                        if(array[1][index[1]] >= array[5][index[5]]){ //修改了结束月份列表后,判断结束日期列表如何修改
                            this.multiArray[6] = this.getday(index[2]+1,array[5][index[5]],array[4][index[4]])
                        }else{
                            this.multiArray[6] = this.getday(1,array[5][index[5]],array[4][index[4]])
                        }
                    }else{  //如果开始年份小于结束年份,需要显示所有月份和所有日期
                        this.multiArray[5] = this.getmonth()
                        this.multiArray[6] = this.getday(1,array[5][index[5]],array[4][index[4]])
                    }
                }else if(column == 1 || column == 5 ){ //月份发生改变,响应的日期列表也要改变
                    this.multiArray[column+1] = this.getday(1,array[column][index[column]],array[column-1][index[column-1]])
                    //年份相同的时候,开始月份不能大于结束月份
                    if(array[0][index[0]] == array[4][index[4]] ){
                        let monthi = parseInt(array[1][index[1]])
                        this.multiArray[5] = this.getmonth(monthi)
                        if(array[5].length<=index[5]){//如果结束月份列表长度不足,显示列表头
                            this.multiIndex[5] = 0
                        }
                        //判断一下月份,不判断下标是因为两个列表的长度很可能不同
                        let value = array[column][index[column]]
                        if((value == 4 || value == 6 || value == 9 || value == 11) && index[column+1] == 30 ){
                            this.multiIndex[2] = 29
                            this.multiIndex[6] = 29
                        }else if(value == 2 && index[column+1] > 27){
                            this.multiIndex[2] = 27
                            this.multiIndex[6] = 27
                        }
                        //修改结束日期列表
                        if(array[1][index[1]] == array[5][index[5]]){
                            this.multiArray[6] = this.getday(array[2][index[2]],array[5][index[5]],array[4][index[4]])
                        }
                    }
                }else if(column == 2 && array[0][index[0]] == array[4][index[4]] && array[1][index[1]] == array[5][index[5]]){
                    //如果年份和月份都相同,同步结束日期,日期上滑也得同步,否则就得再定位array[6][index[6]]
                    this.multiArray[6] = this.getday(array[2][index[2]],array[1][index[1]],array[0][index[0]])
                    if(array[6].length<=index[6]){//如果结束日期列表长度不足,显示列表头
                        this.multiIndex[6] = 0
                    }
                }
                
            },
            getyear(e){
                let year = e?e:2010
                let years = []
                for (let i = year; i <= new Date().getFullYear() + 5 ; i++) {
                    years.push("" + i);
                }
                return years
            },
            getmonth(e){
                let month = e?e:1 
                let months = []
                for (let i = month; i <= 12; i++) {
                    if (i < 10) {
                        i = "0" + i;
                    }
                    months.push("" + i);
                }
                return months
            },
            getday(d,m,y){ 
                let dm = 31
                if (m == 4 || m == 6 || m == 9 || m == 11){
                    dm = 30
                    if(d == 31){
                        d = 30
                    }
                }else if( m == 2 ){
                    if(y % 400 == 0  || ( y % 4 == 0 || y % 100 != 0)){
                        dm = 29
                    }else{
                        dm = 28
                    }
                    if(d > dm){
                        d = dm
                    }
                }
                let days = []
                for (let i = d; i <= dm; i++) {
                    if (i < 10  &&i.length ===1) {
                        i = "0" + i;
                    }
                    days.push("" + i);
                }
                return days
            },
		}
	})
</script>

json部分: //再次在这里说明我使用的是mpx框架,和原生不太一样

<script type="application/json">
  {
    "component": true
  }
</script>

css部分没有

ps:写这篇博文的时候才发现自己的第一篇博文没发出去…

时过境迁,拿来放到原生小程序上才发现,wx.setData好恶心…而且代码里还有几个小bug

又时过境迁,找不到上套代码了,只能来拿原生的改


data: {
    listdata: [],
    time: [],
    multiArray: [
      [],
      [],
      [], "-", [],
      [],
      []
    ],
    multiIndex: [],
    oldDate: [0, 0, 0]
  },

getThisDate() {
    let date = new Date(); //获取完整的年份(4位,1970-????)
    let year = date.getFullYear()
    let month = date.getMonth()
    let day = date.getDate()

    let lists = [year - 2010, month, 0, 0, 0, 0, 0]
    let years = this.getyear(2010)
    let months = this.getmonth(1)
    let days = this.getday(1)
    let years2 = this.getyear(year)
    let months2 = this.getmonth(month + 1)
    let days2 = this.getday(day, month, year)

    this.setData({
      oldDate: [year, month + 1, day],
      multiIndex: lists,
      multiArray: [years, months, days, "-", years2, months2, days2]
    })
    let e = {
      detail: {
        value: lists
      }
    }
    this.bindMultiPickerChange(e)
  },
  bindMultiPickerChange(e) {
    // console.log('picker发送选择改变,携带值为', e.detail.value)
    const index = this.data.multiIndex
    const year = this.data.multiArray[0][index[0]]
    const month = this.data.multiArray[1][index[1]]
    const day = this.data.multiArray[2][index[2]]
    const year2 = this.data.multiArray[4][index[4]]
    const month2 = this.data.multiArray[5][index[5]]
    const day2 = this.data.multiArray[6][index[6]]
    this.setData({
      multiIndex: e.detail.value,
      time: [year + '-' + month + '-' + day, year2 + '-' + month2 + '-' + day2]
    })
    this.getData()
  },
  //监听picker的滚动事件, TUDO 这个组件可能还有bug,需要测试大哥的努力了 
  bindMultiPickerColumnChange(e) {
    //获取年份
    const column = e.detail.column
    const array = this.data.multiArray //例 array[0][index[0]] 代表开始年份的值 array[0]代表开始年份列表
    const index = this.data.multiIndex // index[0] 代表开始年份的下标
    const oldDate = this.data.oldDate
    let up = "multiIndex[" + column + "]";
    this.setData({
      [up]: e.detail.value
    })
    // console.log('修改的列为',column, ',值为', e.detail.value);
    if (column == 0) {
      //修改开始年份需要同步更新结束年份列表,还得同步更新点开始日期列表
      let ma2 = "multiArray[2]"
      let ma4 = "multiArray[4]"
      let mi4 = "multiIndex[4]"
      this.setData({
        [ma2]: this.getday(1, array[1][index[1]], array[0][index[0]]),
        [ma4]: this.getyear(array[0][index[0]])
      })
      let _index4 = index[4]
      let _num4 = 0
      _num4 = oldDate[0] - array[0][index[0]]
      _index4 += _num4
      if (_index4 < 0) _index4 = 0
      let old0 = "oldDate[0]"
      this.setData({
        [old0]: array[0][index[0]],
        [mi4]: _index4
      })
      if (array[4].length <= index[4]) { //如果结束年份列表长度不足,显示列表头
        this.setData({
          [mi4]: 0
        })
      }
      if (array[1][index[1]] == array[5][index[5]]) { //如果月份相同,同步结束日期列表
        let ma6 = "multiArray[6]";
        this.setData({
          [ma6]: this.getday(index[2] + 1, array[5][index[5]], array[4][index[4]])
        })
      }
    } else if (column == 4) {
      //修改结束年份需要修改 结束日期列表 和 结束月份列表,如果 开始年份和结束年份 一致,开始月份不能小于结束月份,
      let ma5 = "multiArray[5]";
      let ma6 = "multiArray[6]";
      let _data5 = ""
      let _data6 = ""
      if (array[0][index[0]] == array[4][index[4]] && array[1][index[1]] > array[5][index[5]]) {
        _data5 = this.getmonth(index[1] + 1)
        if (array[1][index[1]] >= array[5][index[5]]) { //修改了结束月份列表后,判断结束日期列表如何修改
          _data6 = this.getday(index[2] + 1, array[5][index[5]], array[4][index[4]])
        } else {
          _data6 = this.getday(1, array[5][index[5]], array[4][index[4]])
        }
        this.setData({
          [ma5]: _data5,
          [ma6]: _data6
        })
      } else { //如果开始年份小于结束年份,需要显示所有月份和所有日期
        _data5 = this.getmonth()
        _data6 = this.getday(1, array[5][index[5]], array[4][index[4]])
      }
      this.setData({
        [ma5]: _data5,
        [ma6]: _data6
      })
    } else if (column == 1 || column == 5) { //月份发生改变,响应的日期列表也要改变
      let mi5 = "multiIndex[5]";
      let old1 = "oldDate[1]"
      if (column == 1) {
        let _index5 = index[5]
        let _num5 = 0
        _num5 = oldDate[1] - array[1][index[1]]
        _index5 += _num5
        if (_index5 < 0) _index5 = 0
        this.setData({
          [old1]: array[1][index[1]],
          [mi5]: _index5
        })
      }
      let _index = column + 1
      let mai = "multiArray[" + _index + "]";
      console.log(mai);
      console.log(this.getday(1, array[column][index[column]], array[column - 1][index[column - 1]]));
      this.setData({
        [mai]: this.getday(1, array[column][index[column]], array[column - 1][index[column - 1]])
      })
      //年份相同的时候,开始月份不能大于结束月份
      if (array[0][index[0]] == array[4][index[4]]) {
        let monthi = parseInt(array[1][index[1]])
        let ma5 = "multiArray[5]";
        this.setData({
          [ma5]: this.getmonth(monthi)
        })

        if (array[5].length <= index[5]) { //如果结束月份列表长度不足,显示列表头
          this.setData({
            [mi5]: 0
          })
        }
        //判断一下月份,不判断下标是因为两个列表的长度很可能不同
        let value = array[column][index[column]]
        let mi2 = "multiIndex[2]";
        let mi6 = "multiIndex[6]";

        let _datai2 = this.data.multiIndex[2]
        let _datai6 = this.data.multiIndex[6]
        if ((value == 4 || value == 6 || value == 9 || value == 11) && index[column + 1] == 30) {
          _datai2 = 29
          _datai6 = 29
        } else if (value == 2 && index[column + 1] > 27) {
          _datai2 = 27
          _datai6 = 27
        }
        this.setData({
          [mi2]: _datai2,
          [mi6]: _datai6
        })
        //修改结束日期列表
        if (array[1][index[1]] == array[5][index[5]]) {
          let ma6 = "multiArray[6]";
          this.setData({
            [ma6]: this.getday(array[2][index[2]], array[5][index[5]], array[4][index[4]])
          })
        }
      }
    } else if (column == 2 && array[0][index[0]] == array[4][index[4]] && array[1][index[1]] == array[5][index[5]]) {
      //如果年份和月份都相同,同步结束日期,日期上滑也得同步,否则就得再定位array[6][index[6]]
      let ma6 = "multiArray[6]";
      let mi6 = "multiIndex[6]";
      let old2 = "oldDate[2]"

      let _index6 = index[6]
      let _num6 = 0
      _num6 = oldDate[2] - array[2][index[2]]
      _index6 += _num6
      if (_index6 < 0) _index6 = 0
      this.setData({
        [old2]: array[2][index[2]],
        [ma6]: this.getday(array[2][index[2]], array[1][index[1]], array[0][index[0]]),
        [mi6]: _index6
      })
      if (array[6].length <= index[6]) { //如果结束日期列表长度不足,显示列表头
        let mi6 = "multiIndex[6]";
        this.setData({
          [mi6]: 0
        })
      }
    }

  },
  getyear(e) {
    let year = e || 2010
    let years = []
    for (let i = year; i <= new Date().getFullYear() + 5; i++) {
      years.push("" + i);
    }
    return years
  },
  getmonth(e) {
    let month = e || 1
    let months = []
    for (let i = month; i <= 12; i++) {
      if (i < 10) {
        i = "0" + i;
      }
      months.push("" + i);
    }
    return months
  },
  getday(d, m, y) {
    let dm = 31
    if (m == 4 || m == 6 || m == 9 || m == 11) {
      dm = 30
      if (d == 31) {
        d = 30
      }
    } else if (m == 2) {
      if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0) {
        dm = 29
      } else {
        dm = 28
      }
      if (d > dm) {
        d = dm
      }
    }
    let days = []
    for (let i = d; i <= dm; i++) {
      if (i < 10 && i.length === 1) {
        i = "0" + i;
      }
      days.push("" + i);
    }
    return days
  },

这个是小程序的代码了

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值