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

论坛 期权论坛 脚本     
匿名技术用户   2020-12-27 14:50   11   0

微信小程序的双时间选择器基于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]]){
                    //如果年份和月份都相同,同步结束日期
                    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&&((y % 400 == 0) || (y % 100 != 0)) && (y % 4 == 0)){
                        dm = 29
                    }else{
                        dm = 28
                    }
                    if(d > 28){
                        d = 28
                    }
                }
                let days = []
                for (let i = d; i <= dm; i++) {
                    if (i < 10) {
                        i = "0" + i;
                    }
                    days.push("" + i);
                }
                return days
            },
  }
 })
</script>

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

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

css部分没有

ps:写这篇博文的时候才发现自己的第一篇博文没发出去…
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP