开发微信小程序过程中,有个需求需要用到日期时间筛选器,查看微信官方文档后,发现官方文档的picker筛选器只能单独支持日期或者是时间,所以为了实现需求自己参考企业微信封装了个日期时间筛选器组件。

写在前面!!! 由于较多朋友有源码需求,我抽了个时间整理了一下代码,并对一年前的代码进行了升级和优化,并放在我github上,有需要的自取:微信小程序日期时间选择器

原理

筛选器的实现,我参考的是小程序官方方式,通过半屏弹窗(mp-half-screen-dialog)结合picker_view进行日期、时间的选择,最终在选择时间后,通过事件触发返回一个change事件,其中参数值为毫秒级时间戳。需要注意的是,由于组件样式需要,对mp-half-screen-dialog做了一定的样式改造,并且为了不影响全局的mp-half-screen-dialog样式,使用指定的extClass进行样式控制,样式具体实现代码在app.wxss中。

实现

1.弹窗的显隐:
在组件的 properties 中传入一个 show 字段,用于控制弹窗的显隐;默认值为 false
2.开始时间,时间戳:
毫秒级时间戳,非必填,默认为,距现在一年前的时间。
3.结束时间,时间戳:
毫秒级时间戳,非必填,默认为,距现在一年后的时间。

具体思路:整体思路是监听弹窗的显隐(show),当弹窗显示时,获取对应配置项(类型、年、月)计算对应筛选器的范围,并初始化默认日期时间为当前年月日时分

以下是效果图以及具体代码实现:

wxml代码

<!--components/date-time-picker.wxml-->
<mp-half-screen-dialog show="{{ show }}" maskClosable="{{ false }}" closabled="{{ false }}" extClass="date-time-dialog" catchtouchmove="preventTouchMove" bindclose="bindclose"><view slot="desc" class="date-time-container"><view class="date-time-body"><!-- 日期 --><view class="selector-panel selector-panel-date"><picker-view indicator-style="height: 55px;" mode="selector" value="{{ [dateIndex] }}" class="selector-picker" bindchange="dateChange" bindpickstart="bindpickstart" bindpickend="bindpickend"><picker-view-column><view wx:for="{{ dateArr }}" wx:key="index" class="selector-item selector-item-date">{{ item.name }}</view></picker-view-column></picker-view></view><!-- 小时 --><view class="selector-panel"><picker-view indicator-style="height: 55px;" mode="selector" value="{{ [hourValue] }}" class="selector-picker" bindchange="hourChange" bindpickstart="bindpickstart" bindpickend="bindpickend"><picker-view-column><view wx:for="{{ hourArr }}" wx:key="index" class="selector-item">{{ item }}</view></picker-view-column></picker-view></view><!-- 分钟 --><view class="selector-panel"><picker-view indicator-style="height: 55px;" mode="selector" value="{{ [minValue] }}" class="selector-picker" bindchange="minChange" bindpickstart="bindpickstart" bindpickend="bindpickend"><picker-view-column><view wx:for="{{ minArr }}" wx:key="index" class="selector-item">{{ item }}</view></picker-view-column></picker-view></view></view><view class="date-time-oper"><button type="default" class="weui-btn oper-btn" bindtap="bindclose">取消</button><button type="primary" class="weui-btn oper-btn" bindtap="handleSubmit" disabled="{{ disabled }}">确定</button></view></view>
</mp-half-screen-dialog>

js代码

const utils = require('../utils/util')
const yearTimestamp = 365 * 24 * 60 * 60 * 1000 // 一年Component({/*** 组件的属性列表*/properties: {show: {type: Boolean,value: false,observer: '_showChange'},// 开始时间,时间戳startTime: {type: Number,value: +new Date() - yearTimestamp  // 默认,一年前},// 结束时间,时间戳endTime: {type: Number,value: +new Date() + yearTimestamp  // 默认,一年后}},/*** 组件的初始数据*/data: {disabled: false, // button disable态dateIndex: null,hourValue: '',minValue: '',dateArr: [],hourArr: [],minArr: [],activeTime: null // 抛出的时间戳},/*** 组件的方法列表*/methods: {_showChange (e) {if (e) {this.getDateTimeData()this.initData()}},handleSubmit () {this.bindclose()this.triggerEvent('change', { value: this.data.activeTime })},/*** 处理日期时间初始值*/initData () {if (!this.data.activeTime) {const now = +new Date()if (now >= this.data.startTime && now <= this.data.endTime) {const index = this.data.dateArr.map(v => v.name).indexOf(utils.formatTime(now, '{m}月{d}日周{a}'))let tmp = this.data.dateArrtmp[index].name = '今天'this.setData({dateIndex: index,hourValue: utils.formatTime(now, '{h}'),minValue: utils.formatTime(now, '{i}'),dateArr: tmp,activeTime: now})}}},/*** 获取日期时间数据,思路:获取固定的小时、分钟数组,将开始时间、结束时间进行年月天对比,取其差值,从而形成对应日期数组*/getDateTimeData () {const mins = []const hours = []let dates = []// 获取小时、分钟数组for (let i = 0; i < 60; i++) {mins.push(i.toString().length < 2 ? '0' + i : i.toString())}for (let j = 0; j < 24; j++) {hours.push(j.toString().length < 2 ? '0' + j : j.toString())}// 开始时间需小于结束时间if (this.data.startTime >= this.data.endTime) {console.log('error_params_not_valid')return}// 获取日期数组dates = this.getDateData()this.setData({hourArr: hours,minArr: mins,dateArr: dates})},getDateData () {const startDate = new Date(this.data.startTime)const endDate = new Date(this.data.endTime)const nowYear = new Date().getFullYear()const startYear = startDate.getFullYear()const endYear = endDate.getFullYear()const startMonth = startDate.getMonth()const endMonth = endDate.getMonth()const startDay = startDate.getDate()const endDay = endDate.getDate()const dateArr = []// 处理逻辑:判断年限是否相同;若同年则判断是否同月,同月则直接添加日期;不同月则从开始时间月份处理,同时处理月日边界问题;以此类推...let time = 0// 同年if (startYear === endYear) {// 同月if (startMonth === endMonth) {for (let day = startDay; day <= endDay; day++) {time = new Date(startYear, startMonth, day)dateArr.push({ name: startYear === nowYear ? utils.formatTime(time, '{m}月{d}日周{a}') : utils.formatTime(time, '{y}年{m}月{d}日周{a}'), value: time })}} else {// 不同月let tmpDay = startDaylet lastMonth = endMonthfor (let month = startMonth; month <= lastMonth; month++) {// 默认获取的月份方法得到月份值是0-11,该方法获取天数的月份值是1-12const days = month === lastMonth ? endDay : new Date(startYear, month + 1, 0).getDate()for (let day = tmpDay; day <= days; day++) {time = new Date(startYear, month, day)dateArr.push({ name: startYear === nowYear ? utils.formatTime(time, '{m}月{d}日周{a}') : utils.formatTime(time, '{y}年{m}月{d}日周{a}'), value: time })// 处理边界(日)day === days && (tmpDay = 1)}}}} else {// 不同年let tmpDay = startDaylet tmpMonth = startMonthlet lastMonth = 11for (let year = startYear; year <= endYear; year++) {for (let month = tmpMonth; month <= lastMonth; month++) {// 默认获取的月份方法得到月份值是0-11,该方法获取天数的月份值是1-12const days = (month === lastMonth && year === endYear) ? endDay : new Date(startYear, month + 1, 0).getDate()for (let day = tmpDay; day <= days; day++) {time = +new Date(year, month, day)dateArr.push({ name: year === nowYear ? utils.formatTime(time, '{m}月{d}日周{a}') : utils.formatTime(time, '{y}年{m}月{d}日周{a}'), value: time })// 处理边界(日)day === days && (tmpDay = 1)}// 处理边界(月)month === lastMonth && (tmpMonth = 0)month === lastMonth && year === endYear - 1 && (lastMonth = endMonth)}}}return dateArr},dateChange (e) {const day = this.data.dateArr[e.detail.value[0]]let time = day.value + (Number(this.data.hourValue) * 3600 + Number(this.data.minValue) * 60) * 1000this.setData({dateIndex: e.detail.value[0],activeTime: time})},hourChange (e) {const hour = Number(this.data.hourArr[e.detail.value[0]])let time = this.data.dateArr[this.data.dateIndex].value + (hour * 3600 + Number(this.data.minValue) * 60) * 1000this.setData({hourValue: this.data.hourArr[e.detail.value[0]],activeTime: time})},minChange (e) {const min = Number(this.data.minArr[e.detail.value[0]])let time = this.data.dateArr[this.data.dateIndex].value + (Number(this.data.hourValue) * 3600 + min * 60) * 1000this.setData({minValue: this.data.minArr[e.detail.value[0]],activeTime: time})},bindclose () {this.setData({show: false})},bindpickstart () {this.setData({disabled: true})},bindpickend () {this.setData({disabled: false})},preventTouchMove () {// 阻止半屏状态下 页面滑动}}
})

wxss代码

.date-time-container {min-height: 350px !important;display: flex;flex-direction: column;
}.date-time-body {width: 100% !important;display: flex;flex: auto;
}.date-time-oper {flex: none;display: flex;justify-content: space-between;align-items: center;
}.selector-panel {width: 80px;display: flex;align-items: center;
}
.selector-panel-date {flex: auto;
}.selector-picker {width: 100%;height: 80%;font-size: 24px;
}.selector-item {line-height: 50px !important;text-align: center;
}.selector-item-date{font-size: 16px;
}.oper-btn {width: 45% !important;height: 40px !important;
}

微信小程序之日期时间筛选器实现(支持年月日时分)相关推荐

  1. 微信小程序时间范围日期时间选择器

    效果如图: 仓库地址

  2. 微信小程序根据日期和时间进行排序

    一.前言 最近接手了一个小程序的项目,有这样一个需求要对列表进行日期和时间的排序,于是小试牛刀,操作了一番,终于搞出来,在这里给大家总结分享一下经验,希望对大家有一定的帮助. 二.需求分析(这是已完成 ...

  3. 微信小程序时间加法_微信小程序获取系统时间、时间戳、时间时间戳加减

    微信小程序获取系统时间.时间戳.时间时间戳加减,微信小程序获取明天时间 //获取当前时间戳 var timestamp = Date.parse(new Date()); timestamp = ti ...

  4. 微信小程序渲染实时时间

    微信小程序渲染实时时间 1.看看在框架目录中是否有util文件夹,它用来存放工具栏的JavaScript函数 2.在要获取时间的.js文件中加载util.js文件 3.在onload方法中,调用uti ...

  5. 基于java SSM框架+微信小程序实现电子书城阅读器演示【附项目源码+论文说明】分享

    基于java SSM框架+微信小程序实现电子书城阅读器演示 摘要 而随着互联网技术的不断发展,互联网已经渗入到我们生活中的各个方面.移动设备的普及使我们的生活发生了翻天覆地的变化,这种变化也深刻影响着 ...

  6. 基于java SSM框架+微信小程序实现电子书城阅读器演示【附项目源码+论文说明】

    基于java SSM框架+微信小程序实现电子书城阅读器演示 摘要 而随着互联网技术的不断发展,互联网已经渗入到我们生活中的各个方面.移动设备的普及使我们的生活发生了翻天覆地的变化,这种变化也深刻影响着 ...

  7. 微信小程序账号长时间未登录冻结解封

    微信小程序账号长时间未登录冻结解封 1.账号找回链接[官方]:http://mp.weixin.qq.com/acct/findacct?action=scan 2.按照官方指引的三个操作步骤进操作, ...

  8. 微信小程序多维数组筛选(以二维数组为例)

    微信小程序多维数组筛选(以二维数组为例) 我们在遇到微信小程序进行筛选的时候,一般会使用到filter函数来进行筛选,但是有时候遇到多维数组怎么办呢? //例如这是我们的数组 arr: [{id: 1 ...

  9. 关于微信小程序iOS端时间格式兼容问题

    关于微信小程序iOS端时间格式兼容问题 在自己开发中,当时间格式为 2020-06-29 08:00 ,需要将时间转为其他格式时,Android端转换成功,iOS端报错或是转为NaN. 解决方法: 1 ...

最新文章

  1. Windows 10 又在生产环境进行测试?微软:发错了
  2. 用 Flask 来写个轻博客 (14) — M(V)C_实现项目首页的模板
  3. 重新学.Net[四]——效率和安全
  4. 破解微软xp黑屏方法
  5. kafka高性能揭秘:顺序写和零拷贝
  6. php动态写入vue,Vue自定义动态组件使用详解
  7. Python与C之间的相互调用(Python C API及Python ctypes库)
  8. 遥感图像增强方法应用
  9. golang---map类型
  10. YV12 and NV12异同,
  11. 一文教你如何用 Python 将 iPhone “玩弄于股掌之中”!
  12. 华为 “OSPF” 多区域配置
  13. Go Slice 高级实践
  14. tensorflow Keras的搭建训练步骤
  15. ★★★★★手把手教你如何利用凤凰实现破 解后台权限以及升级固件(刷机)★★★★★
  16. jquery触屏幻灯片
  17. leetcode 714 买卖股票的最佳时机含手续费-动态规划(中等)
  18. RxSwift 的简单使用
  19. 使用Python将多个单独的Excel文件整合到一个Excel文件的不同工作表里
  20. java如何创建列表的表头,java word设置表头

热门文章

  1. Windows编程画太极图
  2. linux /etc/security/login.cfg,AIX用户管理
  3. python特征选择relieff图像特征优选_基于Relief特征选择算法的研究与应用
  4. 决策树——(一)决策树的思想
  5. uni-app如何自定义内容生成二维码?
  6. CreateFont(MFC)字体设计
  7. TRUNCATE 命令用法
  8. python获取网页内容 不打开_网页抓取python不返回任何内容
  9. 2021年安全员-B证找解析及安全员-B证模拟考试题
  10. chrome浏览器中自带input样式input:-internal-autofill-selected(修改input背景色)