基于pick-view时间组件

做一个时间选择器

最近需要做一个小程序项目的时候,遇到一个需要将时间选择器暴露在页面的需求。
如图:


需求图

pick view

微信小程序提供了一些非常常见的pick组件,但是直接暴露在页面上的,只有pick view组件。因此这边只能使用这个了。😂

不上台面的代码片段

由于项目比较急,没有时间做优化,因此直接开搞。这边贴上代码。🤒
😈😈⚠️警告: 目前picker-view不支持给选中的column改变字体颜色,因此无法高亮选中的picker-view-column哪怕设置indicator-style或者给加上indicator-class都不好用!
但是可以给indicator-style添加背景色,就像这样 indicator-style="background:#ff4400;"。😂😂但是。。真的很丑😫😫😫😫

view 代码

   <picker-view indicator-style="height: 45px;"  indicator-class="indicator" bindchange="bindChange" value='{{defaultDate}}'>
      <picker-view-column>
        <view class='year' wx:for="{{years}}" wx:key="{{index}}">{{item}}</view>
      </picker-view-column>
      <picker-view-column>
        <view class='month' wx:for="{{months}}" wx:key="{{index}}">{{item}}</view>
      </picker-view-column>
      <picker-view-column>
        <view class='day' wx:for="{{days}}" wx:key="{{index}}">{{item}}</view>
      </picker-view-column>
      <picker-view-column>
        <view class='hour' wx:for="{{hours}}" wx:key="{{index}}">{{item}}</view>
      </picker-view-column>
      <picker-view-column>
        <view class='min' wx:for="{{mins}}" wx:key="{{index}}">{{item}}</view>
      </picker-view-column>
    </picker-view>

公共js代码

Array.prototype.indexVf = function(arr) {            
  for (var i = 0; i < this.length; i++) {                
    if (this[i] == arr) {                    
      return i;                
    }            
  }       
}
let years = []
let months = []
let days = []
let hours = []
let mins = []

let date = new Date();

// 格式化数字
function formatNum(val) {
  let formatVal;
  if (val < 10) {
    formatVal = `0${val}`
  } else {
    formatVal = val;
  }
  return formatVal;
}

// 初始化当前时间
function initYear() {
  let date = new Date();
  // 此处清空数组,防止数据污染
  years = [];
  months = [];
  days = [];
  hours = [];
  mins = [];
  for (let i = date.getFullYear(); i <= date.getFullYear() + 5; i++) {
    years.push(i)
  }

  for (let i = date.getMonth() + 1; i <= 12; i++) {
    months.push(formatNum(i));
  }
  // 根据月份 获取当前月的天数
  let countDays = new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();

  for (let i = date.getDate(); i <= countDays; i++) {
    days.push(formatNum(i));
  }

  for (let i = date.getHours(); i <= 23; i++) {
    hours.push(formatNum(i));
  }

  for (let i = date.getMinutes(); i <= 59; i++) {
    mins.push(formatNum(i))
  }

}
// 初始化 所有时间
function initAllYear(yy, mm) {
  // 此处清空数组,防止数据污染
   years = [];
   months = [];
   days = [];
   hours = [];
   mins = [];

  for (let i = date.getFullYear(); i <= date.getFullYear() + 5; i++) {
    years.push(i)
  }

  for (let i = 1; i <= 12; i++) {
    months.push(formatNum(i));
  }
  // 根据月份 获取当前月的天数
  let countDays = new Date(yy, mm, 0).getDate();

  for (let i = 1; i <= countDays; i++) {
    days.push(formatNum(i));
  }


  for (let i = 0; i <= 23; i++) {
    hours.push(formatNum(i));
  }

  for (let i = 0; i <= 59; i++) {
    mins.push(formatNum(i))
  }
}


页面js

page({
    data: {
    years,
    year: "",
    months,
    month: "",
    days,
    day: "",
    hours,
    hour: "",
    mins,
    min: "",
    defaultDate: []
  },
   // 选择大于当前年份的时候 需要重置 月日时分
  reMonDayHourMin(val) {
    // 获取最新日期,防止出现页面长时间停留,造成时间不准
    const date = new Date();
    // 选择了明年以后
    if (this.data.years[val[0]] > date.getFullYear()) {
      let months = [];
      for (let i = 1; i <= 12; i++) {
        months.push(formatNum(i))
      }
      this.setData({
        months
      })
    } else {
      let months = [];
      for (let i = date.getMonth() + 1; i <= 12; i++) {
        months.push(formatNum(i))
      }
      this.setData({
        months
      })
    }
  },
  // 选择本年度 不同月份后  需要重置 日时分
  reDayHourMin(val) {
    // 获取最新日期,防止出现页面长时间停留,造成时间不准
    const date = new Date();
    // 这边选择的月份 可能是 01 02,所以需要将其转成 1 2
    let formatSelMonth = parseInt(this.data.months[val[1]]);
    let countDays = new Date(this.data.years[val[0]], formatSelMonth, 0).getDate();
    let days = [];
    // 当前日期
    let CURDATE = `${date.getFullYear()}${formatNum(date.getMonth() + 1)}`;
    // 选中的日期
    let SELDATE = `${this.data.years[val[0]]}${this.data.months[val[1]]}`;
    if (CURDATE == SELDATE) {
      for (let i = date.getDate(); i <= countDays; i++) {
        days.push(formatNum(i))
      }
      this.setData({
        days
      })
    } else {
      for (let i = 1; i <= countDays; i++) {
        days.push(formatNum(i))
      }
      this.setData({
        days
      })
    }
  },
  // 选择本年度 本月份 不同日期的时候 需要重置 时分
  reHourMin(val) {
    // 获取最新日期,防止出现页面长时间停留,造成时间不准
    const date = new Date();
    // 当前日期
    let CURDATE = `${date.getFullYear()}${formatNum(date.getMonth() + 1)}${formatNum(date.getDate())}`;
    // 选择日期
    let SELDATE = `${this.data.years[val[0]]}${this.data.months[val[1]]}${this.data.days[val[2]]}`;
    let hours = [];
    if (CURDATE == SELDATE) {
      // 重置小时
      for (let i = date.getHours(); i <= 23; i++) {
        hours.push(formatNum(i))
      }
      this.setData({
        hours
      })
    } else {
      for (let i = 0; i <= 23; i++) {
        hours.push(formatNum(i))
      }
      this.setData({
        hours
      })
    }
  },
  // 选择本年度 本月份 同一日期的时候 需要重置 分钟
  reMin(val) {
    // 获取最新日期,防止出现页面长时间停留,造成时间不准
    const date = new Date();
    // 当前日期时间
    let CURDATETIME = `${date.getFullYear()}${formatNum(date.getMonth() + 1)}${formatNum(date.getDate())}${formatNum(date.getHours())}`;
    // 选择日期时间
    let SELDATETIME = `${this.data.years[val[0]]}${this.data.months[val[1]]}${this.data.days[val[2]]}${this.data.hours[val[3]]}`;
    let mins = [];
    if (CURDATETIME == SELDATETIME) {
      // 重置分钟
      for (let i = date.getMinutes(); i <= 59; i++) {
        mins.push(formatNum(i))
      }
      this.setData({
        mins
      })
    } else {
      for (let i = 0; i <= 59; i++) {
        mins.push(formatNum(i))
      }
      this.setData({
        mins
      })
    }
  },
   bindChange(e) {
    // pick view 改变值后的回调
    const val = e.detail.value;
    // 根据选择,重置对应的时间
    this.reMonDayHourMin(val);
    this.reDayHourMin(val);
    this.reHourMin(val);
    this.reMin(val);
    this.setData({
      year: this.data.years[val[0]],
      month: this.data.months[val[1]],
      day: this.data.days[val[2]],
      hour: this.data.hours[val[3]],
      min: this.data.mins[val[4]],
    })
  },
   onLoad: function(options) {
    console.log("options",options);
    let date = new Date();

    let {
        modalCardTime = "",
        modalCardDate = "",
        modalCardName = "",
        modalCardTel = "",
        modalCardAvatar = "",
        modalCardIdolid=""
    } = options;

    this.setData({
      modalCardTime,
      modalCardDate,
      modalCardName,
      modalCardTel,
      modalCardAvatar,
    })

  
    if (clockId > 0) {
      // 用户修改闹钟
      let resetYear;
      let resetMonth;
      let resetDate;
      let resetHour = modalCardTime.split(":")[0];
      let resetMin = modalCardTime.split(":")[1];

      if (modalCardDate == "今天") {
        resetYear = date.getFullYear();
        resetMonth = date.getMonth() + 1;
        resetDate = date.getDate();
      } else if (modalCardDate == "明天") {
        resetYear = date.getFullYear();
        resetMonth = date.getMonth() + 1;
        resetDate = date.getDate() + 1;
      } else {
        resetYear = parseInt(modalCardDate.split('-')[0]);
        resetMonth = parseInt(modalCardDate.split('-')[1]);
        resetDate = parseInt(modalCardDate.split('-')[2]);
      }

      initAllYear(resetYear, resetMonth);
      this.setData({
        years,
        months,
        days,
        hours,
        mins
      })

      let yearIndex = this.data.years.indexVf(resetYear);
      let monthIndex = this.data.months.indexVf(resetMonth);
      let dayIndex = this.data.days.indexVf(resetDate);
      let hourIndex = this.data.hours.indexVf(resetHour);
      let minIndex = this.data.mins.indexVf(resetMin);

      this.setData({
        defaultDate: [yearIndex, monthIndex, dayIndex, hourIndex, minIndex],
      })

    } else {
      initYear();
      this.setData({
        years,
        months,
        days,
        hours,
        mins
      })
    }
  }
})

关于pick-view组件

⚠️⚠️ 这些代码片段是我直接在项目中复制过来的,因此无法直接在小程序跑。这边只是提供了一个简单的思路,给有需要的人或者未来的自己(记忆不好)😂😂😂。

value
NumberArray
数组中的数字依次表示 picker-view 内的 picker-view-column 选择的第几项(下标从 0 开始),数字大于 picker-view-column 可选项长度时,选择最后一项。

  1. pick-view提供了NumberArray类型的value属性,所以他只能是数字组成的数组,[1,2,3,4,5]而不能是["1","2","3","4","5"]。 因此需要做Number化。 通过value属性,我们可以设置默认展示的picker-view-column值。
  2. 因为需求中需要做不足10补零的操作,因此需要转换一下。比如3需要转化成03。但是在通过bindChange后选择出来的就是03了,因此⚠️需要做parseInt操作。可以直接将03转成3;
  3. 需求需要不能选择小于当前时间,即不能出现小于当前时间的选项,因此需要通过几个方法reMonDayHourMin,reDayHourMin,reHourMin,reMin来比对选择的时间和当前的时间,防止出现选择其他时间后,选项不出来的bug。
  4. 最后,在进入页面的时候需要重新获取最新的时间,let date = new date();防止用户长时间停留页面,造成时间不准的情况

Thanks,新的一年。加油!❤️

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354