微信小程序picker组件扩展选择时间到秒插件

创建插件seldatetime

// 插件JS部分
Component({

  // 一些选项
  options: {
    // 样式隔离:apply-shared 父影响子,shared父子相互影响, isolated相互隔离
    styleIsolation:"isolated",
    // 允许多个插槽
    multipleSlots: true
  },

  // 组件的对外属性:在 properties 定义段中,属性名采用驼峰写法(propertyName);在 wxml 中,指定属性值时则对应使用连字符写法(property-name="")
  properties: {
    // 传递默认选中日期
    value: String,
    // 最大时间
    end: String,
    // 最小时间
    start: String
  },

  // 组件的内部数据
  data: {
    currKey: [],// 当前选中的时间下标
    item: [],// 当前选中时间,格式[2023, 12, 22, 10, 8]
    list: [],// 时间多列数据集,格式[[], [], [], [], []]
  },

  // 类似于 mixins 和 traits 的组件间代码复用机制
  behaviors: [],

  // 组件数据字段监听器,用于监听 properties 和 data 的变化
  observers:{},

  // 组件间关系定义
  relations: {},

  // 通过组件的外部类实现父组件控制子自己的样式
  externalClasses: [],

  // 组件生命周期声明对象
  lifetimes: {
    attached(){
      this._initialize()
    },
    moved(){},
    detached(){}
  },

  // 组件所在页面的生命周期声明对象
  pageLifetimes: {
    show(){},
    hide(){},
    resize(){}
  },

  /**
   * 在组件实例刚刚被创建时执行。
   * 组件实例刚刚被创建好时, created 生命周期被触发。此时,组件数据 this.data 就是在 Component 构造器中定义的数据 data。 此时还不能调用 setData 。 通常情况下,这个生命周期只应该用于给组件 this 添加一些自定义属性字段
   */
  created(){},

  /**
   * 在组件实例进入页面节点树时执行
   * 在组件完全初始化完毕、进入页面节点树后, attached 生命周期被触发。此时, this.data 已被初始化为组件的当前值。这个生命周期很有用,绝大多数初始化工作可以在这个时机进行  
   */ 
  attached(){},

  /**
   * 在组件在视图层布局完成后执行
   */
  ready(){},

  /**
   * 在组件实例被移动到节点树另一个位置时执行
   */
  moved() {},

  /**
   * 在组件实例被从页面节点树移除时执行
   * 在组件离开页面节点树后, detached 生命周期被触发。退出一个页面时,如果组件还在页面节点树中,则 detached 会被触发
   */ 
  detached() {},

  /**
   * 每当组件方法抛出错误时执行
   */
  error(){},

  /**
   * 组件的方法,包括事件响应函数和任意的自定义方法
   */
  methods: {
    /**
     * 自定义初始化方法
     */
    _initialize() {
      this.setData({
        item: this.datetimeStringToArray(this.data.value || this.getCurrDatetime()),
      })
      this.setDatetimeList()
    },

    /**
     * value 改变时触发 change 事件,event.detail = {value}
     */
    changeDatetime(e){
      this.triggerEvent('change', {
        value: this.datetimeArrayToString(this.data.item)
      })
    },

    /**
     * 选择每列时间都会触发
     */
    columnChangeDatetime({ detail }){
      var column = detail.column;
      var value = detail.value;
      this.data.item[column] = parseInt(this.data.list[column][value]);
      this.setData({
        item: this.data.item
      })
      this.setDatetimeList()
    },

    /**
     * 设置时间列数据集
     * @param {*} datetime 
     */
    setDatetimeList(){
      var datetime = this.data.item;
      var currYear = new Date().getFullYear();
      var startArr = this.datetimeStringToArray(this.data.start || (currYear - 100) + '-01-01 01:01');
      var endArr = this.datetimeStringToArray(this.data.end || (currYear + 100) + '-12-31 24:59');

      var startStr = startArr.join('');
      var endStr = endArr.join('');
      var datetimeStr = datetime.join('');

      var yearArr = this.getColumnBetweenArray(startArr[0], endArr[0], '年');
      // 计算开始月
      var startMonth = (datetimeStr.substr(0, 4) <= startStr.substr(0, 4) ? startArr[1] : 1);
      // 计算结束月
      var endMonth = (datetimeStr.substr(0, 4) >= endStr.substr(0, 4) ? endArr[1] : 12);
      var monthArr = this.getColumnBetweenArray(startMonth, endMonth, '月');
      
      // 计算开始日
      var startDay = (datetimeStr.substr(0, 6) <= startStr.substr(0, 6) ? startArr[2] : 1);
      // 计算每年这个月的天数
      var dayCount = new Date(datetime[0], datetime[1], 0).getDate();
      // 计算结束日
      var endDay = (datetimeStr.substr(0, 6) >= endStr.substr(0, 6) ? endArr[2] : dayCount);
      var dayArr = this.getColumnBetweenArray(startDay, endDay, '日');

      // 计算开始小时
      var startHour = (datetimeStr.substr(0, 8) <= startStr.substr(0, 8) ? startArr[3] : 1);
      // 计算结束小时
      var endHour = (datetimeStr.substr(0, 8) >= endStr.substr(0, 8) ? endArr[3] : 24);
      var hourArr = this.getColumnBetweenArray(startHour, endHour, '时');

      // 计算开始分钟
      var startMinute = (datetimeStr.substr(0, 10) <= startStr.substr(0, 10) ? startArr[4] : 1);
      // 计算结束分钟
      var endMinute = (datetimeStr.substr(0, 10) >= endStr.substr(0, 10) ? endArr[4] : 59);
      var minuteArr = this.getColumnBetweenArray(startMinute, endMinute, '分');

      // 计算当前时间的下标
      var yearKey = this.getKey(yearArr, datetime[0]);
      var monthKey = this.getKey(monthArr, datetime[1])
      var dayKey = this.getKey(dayArr, datetime[2])
      var hourKey = this.getKey(hourArr, datetime[3])
      var minuteKey = this.getKey(minuteArr, datetime[4])

      this.setData({
        currKey: [yearKey, monthKey, dayKey, hourKey, minuteKey],
        list: [yearArr, monthArr, dayArr, hourArr, minuteArr],
        item: [parseInt(yearArr[yearKey]), parseInt(monthArr[monthKey]), parseInt(dayArr[dayKey]), parseInt(hourArr[hourKey]), parseInt(minuteArr[minuteKey])]
      })
    },

    /**
     * 获取数值之间数据列表
     * @param {*} start 
     * @param {*} end 
     */
    getColumnBetweenArray(start, end, unit){
      var resArray = [];
      for(var i = start;i <= end; i++){
        resArray.push(this.zeroize(i) + unit);
      }
      return resArray;
    },

    /**
     * 获取KEY
     * @param {*} array 
     * @param {*} item 
     */
    getKey(array, item){
      var key = array.findIndex(value => parseInt(item) == parseInt(value));
      if(key === -1){
        return 0;
      }
      return key;
    },

    /**
     * 补零
     * @param {*} number 
     */
    zeroize(number){
      return number < 10 ? '0' + number : number;
    },

    /**
     * 获取当前时间
     */
    getCurrDatetime(){
      var d = new Date();
      var year = d.getFullYear()
      var month = d.getMonth() + 1
      var day = d.getDate();
      var hours = d.getHours()
      var minutes = d.getMinutes()
      return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes;
    },

    /**
     * 时间字符串转数组
     * @param {*} datetime 
     */
    datetimeStringToArray(datetime){
      return datetime.replace(/-|:/g, ' ').split(' ').map(item => parseInt(item));
    },

    /**
     * 时间数组转字符串
     * @param {*} datetime 
     */
    datetimeArrayToString(datetime){
      return datetime[0] + '-' + datetime[1] + '-' + datetime[2] + ' ' + datetime[3] + ':' + datetime[4]
    }
  },
})


// wxml部分
<picker mode="multiSelector" range="{{ list }}" value="{{ currKey }}" bindchange="changeDatetime" bindcolumnchange="columnChangeDatetime">
    <slot></slot>
</picker>

app.json配置

"usingComponents": {
    "d-demo": "../../components/seldatetime/index"
},

page页面中调用

// wxml文件内容
<d-demo value="{{ value }}" start="2020-01-01 05:20" end="2060-12-30 18:51" bindchange="selectDatetime">
    <input value="{{ value }}" placeholder="请选择时间" style="border: 1px solid #e2e2e2;padding: 10px;border-radius: 5px;"  />
</d-demo>

// JS文件内容
Page({

  /**
   * 页面的初始数据
   */
  data: {
    value: '2023-12-22 16:50',
  },

  /**
   * 选择时间
   */
  selectDatetime(e){
    var d = e.detail
    this.setData({
      value: d.value
    })
  }
})

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值