[微信小程序] 原生小程序picker组件实现时间日期的选择

一、 使用原生小程序组件Picker自定义日期时间选择器

1. Picker简单介绍

可以看到Picker类型有5种, 具体可以查看微信开放文档 picker,下面先来讲一下普通选择器的使用。
在这里插入图片描述

》普通选择器的使用

mode="selector" -----普通选择器

value="index"-----value默认为下标

range="{{hospitalList}}"-----hospitalList 用于循环Picker的对象数组

range-key="hospitalName"-----hospitalList 对象数组 中 hospitalName 的值 作为选择器显示内容

<view class="triangle_border_down"> </view> ----- CSS 实现的倒三角形

/* select 倒三角 */ 
.triangle_border_down {
  width: 0;
  height: 0;
  border-width: 5px 5px 0;
  border-style: solid;
  border-color: #999 transparent transparent;
  position: absolute; 
  right: 15px;
  top: 18px; 
}  

wxml

<picker bindchange="bindHospitalChange" mode="selector" value="index" range-key="hospitalName" range="{{hospitalList}}">
	<view class="index-section__title">
		{{hospitalName}} 
		<view class="triangle_border_down"> </view>
	</view>
</picker>

js

data:{
	hospitalList:[
		{id:0,hospitalName:'医院1',logo:'../images/logo1.png' },
		{id:1,hospitalName:'医院2',logo:'../images/logo2.png' },
	]
},
bindHospitalChange: function (e) {//医院选择改变
    // console.log(e) 
    // console.log('选择医院,下标为', e.detail.value)  
    // console.log('选中的医院id为:',this.data.hospitalList[e.detail.value].id) 
    this.setData({
      hospitalID: this.data.hospitalList[e.detail.value].id,//选中的医院id 
      hospitalName: this.data.hospitalList[e.detail.value].hospitalName ,//设置医院的名字
      hospitalImage:this.data.hospitalList[e.detail.value].logo,//医院图片更新 
    }) 
}

》多列选择器的使用(实现时间日期自定义)

wxml

<picker mode="multiSelector" bindchange="bindMultiPickerChange"  bindcolumnchange="bindMultiPickerColumnChange" value="{{multiIndex}}" range="{{multiArray}}"> 
		{{time}}
	<view class="triangle_border_down"> </view>
</picker>

js

const DatePickerUtil = require('../../utils/DatePicker.js') 

data: {
	time:'预约稍后时间',
    // multiArray: [years, months, days, hours, minutes],
    // multiIndex: [0, 4, 5, 10, 17],//当前选择列的下标
    multiArray:[],//piker的item项
    multiIndex:[],//当前选择列的下标

},
onShow:function(){
	//设置多列选择器的初始数据 (调用工具类的方法取出初始化多列选择器的初始数据)
    var  loadPickerData=DatePickerUtil.loadPickerData()//picker数组赋值
    var  getCurrentDate=DatePickerUtil.getCurrentDate()//设置当前时间
    var  GetMultiIndex=DatePickerUtil.GetMultiIndex()//设置pickerIndex
    // console.log('loadPickerData',loadPickerData)
    // console.log('getCurrentDate',loadPickerData)
    // console.log('GetMultiIndex',loadPickerData)
    this.setData({ 
      // multiArray: [years, months, days, hours, minutes],
      // multiIndex:[0,currentMonths-1,currentDay-1,currentHours,currentMinute],//设置pickerIndex
      // time:currentYears+'-'+mm+'-'+dd+' '+hh+':'+min //设置当前日期
      multiArray:loadPickerData,//picker数组赋值
      multiIndex:GetMultiIndex,//设置pickerIndex
      time:getCurrentDate, //设置当前时间
      choose_year:loadPickerData[0][0],//现在默认的年份 
    }); 
},
 bindMultiPickerChange: function(e) { //时间日期picker选择改变
    // console.log('picker发送选择改变,携带值为', e.detail.value)
    this.setData({
      multiIndex: 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 hour = this.data.multiArray[3][index[3]];
    const minute = this.data.multiArray[4][index[4]];
    //console.log(`${year}-${month}-${day} ${hour}:${minute}`); 
    this.setData({
      time: year+ month+ day + ' ' + hour.replace('时','')+':'+minute.replace('分','')//显示XXXX年XX月XX日XX时XX分
    })
    ///console.log(this.data.time);
  }, 
  bindMultiPickerColumnChange: function(e) { //监听picker的滚动事件
    //获取年份
    if (e.detail.column == 0) {
      let choose_year = this.data.multiArray[e.detail.column][e.detail.value];
      // console.log(choose_year);
      this.setData({
        choose_year
      })
    }
     console.log('修改的列为', e.detail.column, ',值为', e.detail.value);
    if (e.detail.column == 1) {
      let num = parseInt(this.data.multiArray[e.detail.column][e.detail.value]);
      let temp = [];
      if (num == 1 || num == 3 || num == 5 || num == 7 || num == 8 || num == 10 || num == 12) { //判断31天的月份
        for (let i = 1; i <= 31; i++) {
          if (i < 10) {
            i = "0" + i;
          }
          temp.push("" + i+'日');
        }
        this.setData({
          ['multiArray[2]']: temp
        });
      } else if (num == 4 || num == 6 || num == 9 || num == 11) { //判断30天的月份
        for (let i = 1; i <= 30; i++) {
          if (i < 10) {
            i = "0" + i;
          }
          temp.push("" + i+'日');
        }
        this.setData({
          ['multiArray[2]']: temp
        });
      } else if (num == 2) { //判断2月份天数
        let year = parseInt(this.data.choose_year);
        //console.log(year);
        if (((year % 400 == 0) || (year % 100 != 0)) && (year % 4 == 0)) {
          for (let i = 1; i <= 29; i++) {
            if (i < 10) {
              i = "0" + i;
            }
            temp.push("" + i+'日');
          }
          this.setData({
            ['multiArray[2]']: temp
          });
        } else {
          for (let i = 1; i <= 28; i++) {
            if (i < 10) {
              i = "0" + i;
            }
            temp.push("" + i+'日');
          }
          this.setData({
            ['multiArray[2]']: temp
          });
        }
      }
      //console.log(this.data.multiArray[2]);
    }
    var data = {
      multiArray: this.data.multiArray,
      multiIndex: this.data.multiIndex
    };
    data.multiIndex[e.detail.column] = e.detail.value;
    this.setData(data);
  },


工具类 …/utils/DatePicker.js

// DatePicker.js
const date = new Date();   
var currentYears=date.getFullYear();
var currentMonths=date.getMonth()+1;
var currentDay=date.getDate();
var currentHours=date.getHours();
var currentMinute=date.getMinutes(); 

const formatNumber = n => {

  // formatNumber中获取到n为时间,将它字符串转换,然后检查这个字符串是单是双,
  // 由n[1]就可以判断单双,因为如果是单只有n[0],如果是双就是n[0][1]。所以判断出单双后,如果是单添加一个0到数字前方,如果是双则直接返回。
  
  n = n.toString()
  return n[1] ? n : '0' + n
}


function getCurrentDate(){
    // 获取当前时间   
    var mm=[currentMonths].map(formatNumber)
    var dd=[currentDay].map(formatNumber)
    var hh=[currentHours].map(formatNumber)
    var min=[currentMinute].map(formatNumber) 
    // console.log(currentYears+'年'+mm+'月'+dd+'日'+hh+':'+min)
    return currentYears+'年'+mm+'月'+dd+'日'+hh+':'+min;
}

function GetMultiIndex(){
  //一点开picker的选中设置
  // [0,currentMonths-1,currentDay-1,currentHours,currentMinute]
  return  [0,currentMonths-1,currentDay-1,currentHours,currentMinute]
} 
function loadPickerData(){
  // picker控件初始化
  const years = []; const months = []; const days = []; const hours = []; const minutes = [];
  
  //获取年(现在自定义只有两个年份,自行修改)
  
  for (let i = currentYears; i <= date.getFullYear() + 1; 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 = 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+"分");
  } 
  return [years, months, days, hours, minutes]
}


module.exports = {
  loadPickerData:loadPickerData,
  getCurrentDate:getCurrentDate,
  GetMultiIndex:GetMultiIndex
}

其他 piker 类型暂时没用过,具体看文档吧


又来新的需求,客户说预约时间,开始时间为从今日开始,之前的日期不可选,于是我又开始了填坑之路(重写)

DatePicker.js

const formatNumber = n => {
  n = n.toString()
  return n[1] ? n : '0' + n
}
function getCurrentDate(){// 获取当前时间
  let date = new Date();   
  let currentYears=date.getFullYear();
  let currentMonths=date.getMonth()+1;
  let currentDay=date.getDate();
  let currentHours=date.getHours();
  let currentMinute=date.getMinutes();   
  
  var mm=[currentMonths].map(formatNumber)
  var dd=[currentDay].map(formatNumber)
  var hh=[currentHours].map(formatNumber)
  var min=[currentMinute].map(formatNumber) 
   
  return currentYears+'年'+mm+'月'+dd+'日'+hh+':'+min;
}

function GetMultiIndex(){ //一点开picker的选中设置  
 
  return [0,0,0,0,0]; //现在全部列,默认选第一个选项,其实这一步多余,可以直接在data里面定义 
} 
 
function loadYears(startYear,endYear){//获取年份 
  /**
   * params参数
   * startYear 当前年份
   * endYear 循环结束月份 ,比如 5 年内 newDate().getFullYear() + 4,客户说只能预约两年内 
   * return 年份数组
  */
  let years=[];
  for (let i = startYear; i <= endYear; i++) {
    years.push("" + i+"年");
  } 
  return years;//返回年份数组 
}


function loadMonths(startMonth,endMonth){//获取月份
   /**
   * params参数
   * startMonth 当前月份
   * endMonth 循环结束月份,一般为 12个月
   * return 月份数组
  */ 
  let months=[];
  for (let i = startMonth; i <= endMonth; i++) {
    if (i < 10) {
      i = "0" + i;
    }
    months.push("" + i+"月");
  } 
  return months;//返回月份数组 
}


function loadDays(currentYears,selectedMonths,startDay){ //获取日期  
  /**
   * params参数
   * currentYears 当前年份
   * selectedMonths 当前选择的月份
   * startDay   循环开始日 一般为1号, 希望从当前月份开始 ,startDay=currentDay
   * return 日期数组
  */
    let days=[];
    if (selectedMonths == 1 || selectedMonths == 3 || selectedMonths == 5 || selectedMonths == 7 || selectedMonths == 8 || selectedMonths == 10 || selectedMonths == 12) { //判断31天的月份,可以用正则简化
      for (let i = startDay; i <= 31; i++) {
        if (i < 10) {
          i = "0" + i;
        }
        days.push("" + i+'日');
      } 
    } else if (selectedMonths == 4 || selectedMonths == 6 || selectedMonths == 9 || selectedMonths == 11) { //判断30天的月份
      for (let i = startDay; i <= 30; i++) {
        if (i < 10) {
          i = "0" + i;
        }
        days.push("" + i+'日');
      } 
    } else if (selectedMonths == 2) { //判断2月份天数
      let year = currentYears 
      if (((year % 400 == 0) || (year % 100 != 0)) && (year % 4 == 0)) {//闰年
        for (let i = startDay; i <= 29; i++) {
          if (i < 10) {
            i = "0" + i;
          }
          days.push("" + i+'日');
        }
        
      } else {//不是闰年
        for (let i = startDay; i <= 28; i++) {
          if (i < 10) {
            i = "0" + i;
          }
          days.push("" + i+'日');
        } 
      }
    }
    return days;//返回日期数组
}


function loadHours(startHour,endHour){//获取小时
   /**
   * params参数
   * startHour 循环开始小时 一般为 0点, 希望从当前小时开始 startHour=currentHours
   * endHour 循环当前小时 ,一般为24个小时
   * return 小时数组
  */ 
  let hours=[];
   for (let i = startHour; i < endHour ; i++) {
    // if (i < 10) {//看需求要不要加在前面+0
    //   i = "0" + i;
    // }
    hours.push("" + i+"时");
  }
  return hours;//返回小时数组 
}


function loadMinutes(startMinute,endMinute){//获取分钟
  /**
   * params参数
   * startMinute 循环开始分钟 一般为 0 开始,从当前分钟开始 startMinute=currentMinutes
   * endMinute 循环当前秒 ,一般为60分钟
   * return 分钟数组
  */  
 let minutes=[];
  for (let i = startMinute; i < endMinute ; i++) {
   if (i < 10) {
     i = "0" + i;
   }
   minutes.push("" + i+"分");
 }
 return minutes;//返回分钟数组 
}

//我没有用到秒,可以参考分钟的写法

function loadPickerData(){ //将Picker初始数据,开始时间设置为当前时间
  let date1 = new Date();   
  let currentYears=date1.getFullYear();
  let currentMonths=date1.getMonth()+1;
  let currentDay=date1.getDate();
  let currentHours=date1.getHours();
  let currentMinute=date1.getMinutes();  
  
  // 下面调用 自定义方法 

  //获取年份  loadYears(startYear,endYear)  
  //获取月份  loadMonths(startMonth,endMonth)
  //获取日期  loadDays(currentYears,currentMonths,startDay)
  //获取小时  loadHours(startHour,endHour)
  //获取分钟  loadMinutes(startMinute,endMinute)
  
  let years = loadYears(currentYears,date1.getFullYear() + 1)  //客户说只能预约两年内,+1
  let months = loadMonths(currentMonths,12)   
  let days = loadDays(currentYears,currentMonths,currentDay)  
  let hours = loadHours(currentHours,24)  
  let minutes =  loadMinutes(currentMinute,60)
  
  return [years, months, days, hours, minutes]
}
 
//导出
module.exports = {
  loadPickerData:loadPickerData,
  getCurrentDate:getCurrentDate,
  GetMultiIndex:GetMultiIndex,
  loadYears:loadYears,
  loadMonths:loadMonths,
  loadDays:loadDays,
  loadHours:loadHours,
  loadMinutes:loadMinutes
}

为什么会把年月日时分单独抽出来一个方法导出呢,后面选择单列时,你就知道了(哭)

index.js

const DatePickerUtil = require('../../utils/DatePicker.js') 

Page({
  data: {
  	time:'选择预约时间',
    multiArray:[],//piker的item项
    multiIndex:[],//当前选择列的下标
    year:'',//选择的年
    month:'',//选择的月
    day:'',//选择的日
    hour:'',//选择的时
    minute:'',//选择的分
	}, 
  onShow: function () {
    //获取 DatePickerUtil 工具下的方法
    var  loadPickerData=DatePickerUtil.loadPickerData()
    var  getCurrentDate=DatePickerUtil.getCurrentDate()
    var  GetMultiIndex=DatePickerUtil.GetMultiIndex() 
    
    //这里写的是为了记录当前时间
    let year=parseInt(getCurrentDate.substring(0,4)); 
    let month=parseInt(getCurrentDate.substring(5,7)); 
    let day=parseInt(getCurrentDate.substring(8,10)); 
    let hour=parseInt(getCurrentDate.substring(11,13));   
    let minute=parseInt(getCurrentDate.substring(14,16)); 
    
    this.setData({  
      multiArray:loadPickerData,//picker数组赋值,格式 [years, months, days, hours, minutes]
      multiIndex:GetMultiIndex,//设置pickerIndex,[0,0,0,0,0]
      time:getCurrentDate, //设置当前时间 ,currentYears+'-'+mm+'-'+dd+' '+hh+':'+min
      year:year,//记录选择的年
      month:month,//记录选择的月
      day:day,//记录选择的日
      hour:hour,//记录选择的时
      minute:minute,//记录选择的分 
    });   

  },
 bindMultiPickerChange: function(e) { //时间日期picker选择改变后,点击确定 
    // console.log('picker发送选择改变,携带值为', e.detail.value)
    this.setData({
      multiIndex: 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 hour = this.data.multiArray[3][index[3]];
    const minute = this.data.multiArray[4][index[4]];
    // console.log(`${year}-${month}-${day} ${hour}:${minute}`); 
    
    this.setData({
      time: year+ month+ day + ' ' + hour.replace('时','')+':'+minute.replace('分',''),
      year:year, //记录选择的年
      month:month, //记录选择的月
      day:day, //记录选择的日
      hour:hour, //记录选择的时
      minute:minute, //记录选择的分 
    })
    //console.log(this.data.time); 
  }, 
  bindMultiPickerColumnChange: function(e) { //监听picker的滚动事件
  
    // console.log('修改的列为', e.detail.column, ',值为', e.detail.value);
    
    let getCurrentDate = DatePickerUtil.getCurrentDate();//获取现在时间  
    let currentYear = parseInt(getCurrentDate.substring(0,4)); 
    let currentMonth = parseInt(getCurrentDate.substring(5,7)); 
    let currentDay = parseInt(getCurrentDate.substring(8,10)); 
    let currentHour = parseInt(getCurrentDate.substring(11,13));  
    let currentMinute = parseInt(getCurrentDate.substring(14,16)); 
    
    if (e.detail.column == 0) {//修改年份列 
     
      let yearSelected = parseInt(this.data.multiArray[e.detail.column][e.detail.value]);//当前选择的年份
 
      this.setData({ 
        multiIndex:[0,0,0,0,0] ,//设置pickerIndex
        year:yearSelected //当前选择的年份
      });
      
      if(yearSelected == currentYear){//当前选择的年份==当前年份  
        var loadPickerData=DatePickerUtil.loadPickerData();
        
        this.setData({
          multiArray:loadPickerData,//picker数组赋值
          multiIndex:[0,0,0,0,0] //设置pickerIndex
        });
        
      }else{  // 选择的年份!=当前年份 
      
        // 处理月份
        let monthArr=DatePickerUtil.loadMonths(1,12)
        // 处理日期
        let dayArr=DatePickerUtil.loadDays(currentYear,currentMonth,1) 
        // 处理hour
        let  hourArr=DatePickerUtil.loadHours(0,24); 
        // 处理minute
        let  minuteArr=DatePickerUtil.loadMinutes(0,60)
         
        // 给每列赋值回去
        this.setData({
          ['multiArray[1]']: monthArr,
          ['multiArray[2]']: dayArr,
          ['multiArray[3]']: hourArr,
          ['multiArray[4]']: minuteArr
        });
      }
    }
    if (e.detail.column == 1) {//修改月份列
      let mon = parseInt(this.data.multiArray[e.detail.column][e.detail.value]); //当前选择的月份
      this.setData({
        month:mon  // 记录当前列
      })
      
      if(mon==currentMonth){//选择的月份==当前月份 
        if(this.data.year==currentYear){  
        
          // 处理日期
          let dayArr=DatePickerUtil.loadDays(currentYear,mon,currentDay) 
          // 处理hour
          let  hourArr=DatePickerUtil.loadHours(currentHour,24); 
          // 处理minute
          let  minuteArr=DatePickerUtil.loadMinutes(currentMinute,60)

          this.setData({ 
            ['multiArray[2]']:dayArr,
            ['multiArray[3]']: hourArr,
            ['multiArray[4]']: minuteArr
          })
        }else{ 
          // 处理日期
          let dayArr=DatePickerUtil.loadDays(currentYear,mon,1) 
          // 处理hour
          let  hourArr=DatePickerUtil.loadHours(0,24); 
          // 处理minute
          let  minuteArr=DatePickerUtil.loadMinutes(0,60)
          
          this.setData({
            ['multiArray[2]']:dayArr,
            ['multiArray[3]']: hourArr,
            ['multiArray[4]']: minuteArr
          });
        } 
      }else{  // 选择的月份!=当前月份 
         // 处理日期
         let dayArr = DatePickerUtil.loadDays(currentYear,mon,1) // 传入当前年份,当前选择的月份去计算日
         // 处理hour
         let  hourArr = DatePickerUtil.loadHours(0,24); 
         // 处理minute
         let  minuteArr = DatePickerUtil.loadMinutes(0,60)
         
       	 this.setData({
           ['multiArray[2]']:dayArr,
           ['multiArray[3]']: hourArr,
           ['multiArray[4]']: minuteArr
         });
      } 
    } 
    if(e.detail.column == 2) {//修改日
      let dd = parseInt(this.data.multiArray[e.detail.column][e.detail.value]);//当前选择的日
      this.setData({
        day:dd
      })
      if(dd==currentDay){//选择的日==当前日
        if(this.data.year==currentYear&&this.data.month==currentMonth){//选择的是今天 
        
         // 处理hour
         let  hourArr=DatePickerUtil.loadHours(currentHour,24); 
         // 处理minute
         let  minuteArr=DatePickerUtil.loadMinutes(currentMinute,60)
         
         this.setData({
            ['multiArray[3]']: hourArr,
            ['multiArray[4]']: minuteArr
         });
         
        }else{ //选择的不是今天 
          // 处理hour
          let  hourArr=DatePickerUtil.loadHours(0,24); 
          // 处理minute
          let  minuteArr=DatePickerUtil.loadMinutes(0,60)
          
          this.setData({
             ['multiArray[3]']: hourArr,
             ['multiArray[4]']: minuteArr
          });
        }
      }else{  // 选择的日!=当前日 
       // 处理hour
       let  hourArr=DatePickerUtil.loadHours(0,24); 
       // 处理minute
       let  minuteArr=DatePickerUtil.loadMinutes(0,60)
       
       this.setData({
         ['multiArray[3]']: hourArr,
         ['multiArray[4]']: minuteArr
       });
      }
    } 
    if(e.detail.column == 3) {//修改时
      let hh = parseInt(this.data.multiArray[e.detail.column][e.detail.value]); //当前选择的时
      this.setData({
        hour:hh
      })
      if(hh==currentHour){//选择的时==当前时 
        if(this.data.year==currentYear&&this.data.month==currentMonth&&this.data.month==currentMonth){   // 选择的是今天
          
          // 处理minute
            let  minuteArr=DatePickerUtil.loadMinutes(currentMinute,60)
            this.setData({ 
              ['multiArray[4]']: minuteArr
            });
        }else{ // 选择的不是今天
        
          // 处理minute
          let  minuteArr=DatePickerUtil.loadMinutes(0,60)
          this.setData({ 
            ['multiArray[4]']: minuteArr
          });
        } 
      }else{//选择的时!=当前时 
        // 处理minute
        let  minuteArr=DatePickerUtil.loadMinutes(0,60)
        this.setData({ 
          ['multiArray[4]']: minuteArr
        });
      }
    }
    var data = {
      multiArray: this.data.multiArray,
      multiIndex: this.data.multiIndex
    };

    // console.log('修改的列为', e.detail.column, ',值为', e.detail.value);
    data.multiIndex[e.detail.column] = e.detail.value; //将值赋回去
    
    this.setData(data);  //将值赋回去
  }
})

wxml

<picker bindtap="clickSelectTime" mode="multiSelector" bindchange="bindMultiPickerChange" bindcolumnchange="bindMultiPickerColumnChange" value="{{multiIndex}}" range="{{multiArray}}">
	 {{time}}
	<view class="triangle_border_down"> </view>
</picker>

日期格式化: [微信小程序]日期时间格式化封装Util、ios系统上显示为NaN问题

参考链接: 微信小程序之picker选择器实现时间日期的选择

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值