创建插件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() + 1var 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.detailthis.setData({value: d.value})}
})