背景
由于在项目中遇到需要同时选择日期和时间的需求,所以自己写了一个可以动态配置format格式的时间选择器
效果图
wxml
<view class="view-body">
<text class='item-key'>{{title}}<text style="color:red" wx:if="{{isRequired}}">*</text></text>
<view class="item-value">
<picker mode="multiSelector" bindchange="bindPickerChange" bindcolumnchange="bindPickerColumnChange" value="{{multiIndex}}" range="{{multiArray}}">
<input disabled="{{true}}" value='{{value}}' name='{{name}}' />
<image class="img-arrow" src='/images/date_icon.png' />
</picker>
</view>
</view>
js
Component({
behaviors: ['wx://form-field'],
properties: {
title: {
type: String
},
name: {
type: String
},
isRequired: {
type: Boolean
},
format: {
type: String
}
},
data: {},
lifetimes: {
attached: function() {
//当前时间 年月日 时分秒
const date = new Date()
const curYear = date.getFullYear()
const curMonth = date.getMonth() + 1
const curDay = date.getDate()
const curHour = date.getHours()
const curMinute = date.getMinutes()
const curSecond = date.getSeconds()
//记录默认年份 后面加载二月份天数
this.setData({
chooseYear: curYear
})
//初始化时间选择轴
this.initColumn(curMonth)
//不足两位的前面好补0 因为后面要获取在时间轴上的索引 时间轴初始化的时候都是两位
let showMonth = curMonth < 10 ? ('0' + curMonth) : curMonth
let showDay = curDay < 10 ? ('0' + curDay) : curDay
let showHour = curHour < 10 ? ('0' + curHour) : curHour
let showMinute = curMinute < 10 ? ('0' + curMinute) : curMinute
let showSecond = curSecond < 10 ? ('0' + curSecond) : curSecond
//当前时间在picker列上面的索引 为了当打开时间选择轴时选中当前的时间
let indexYear = this.data.years.indexOf(curYear + '')
let indexMonth = this.data.months.indexOf(showMonth + '')
let indexDay = this.data.days.indexOf(showDay + '')
let indexHour = this.data.hours.indexOf(showHour + '')
let indexMinute = this.data.minutes.indexOf(showMinute + '')
let indexSecond = this.data.seconds.indexOf(showSecond + '')
let multiIndex = []
let multiArray = []
let value = ''
let format = this.properties.format;
if (format == 'yyyy-MM-dd') {
multiIndex = [indexYear, indexMonth, indexDay]
value = `${curYear}-${showMonth}-${showDay}`
multiArray = [this.data.years, this.data.months, this.data.days]
}
if (format == 'HH:mm:ss') {
multiIndex = [indexHour, indexMinute, indexSecond]
value = `${showHour}:${showMinute}:${showSecond}`
multiArray = [this.data.hours, this.data.minutes, this.data.seconds]
}
if (format == 'yyyy-MM-dd HH:mm') {
multiIndex = [indexYear, indexMonth, indexDay, indexHour, indexMinute]
value = `${curYear}-${showMonth}-${showDay} ${showHour}:${showMinute}`
multiArray = [this.data.years, this.data.months, this.data.days, this.data.hours, this.data.minutes]
}
if (format == 'yyyy-MM-dd HH:mm:ss') {
multiIndex = [indexYear, indexMonth, indexDay, indexHour, indexMinute, indexSecond]
value = `${curYear}-${showMonth}-${showDay} ${showHour}:${showMinute}:${showSecond}`
multiArray = [this.data.years, this.data.months, this.data.days, this.data.hours, this.data.minutes, this.data.seconds]
}
this.setData({
value,
multiIndex,
multiArray,
curMonth,
chooseYear: curYear,
})
}
},
/**
* 组件的方法列表
*/
methods: {
//获取时间日期
bindPickerChange: function(e) {
this.setData({
multiIndex: e.detail.value
})
const index = this.data.multiIndex
let format = this.properties.format
var showTime = ''
if (format == 'yyyy-MM-dd') {
const year = this.data.multiArray[0][index[0]]
const month = this.data.multiArray[1][index[1]]
const day = this.data.multiArray[2][index[2]]
showTime = `${year}-${month}-${day}`
}
if (format == 'HH:mm:ss') {
const hour = this.data.multiArray[0][index[0]]
const minute = this.data.multiArray[1][index[1]]
const second = this.data.multiArray[2][index[2]]
showTime = `${hour}:${minute}:${second}`
}
if (format == 'yyyy-MM-dd HH:mm') {
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]]
showTime = `${year}-${month}-${day} ${hour}:${minute}`
}
if (format == 'yyyy-MM-dd HH:mm:ss') {
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]]
const second = this.data.multiArray[5][index[5]]
showTime = `${year}-${month}-${day} ${hour}:${minute}:${second}`
}
this.setData({
value: showTime
})
this.triggerEvent('dateTimePicker', showTime)
},
//初始化时间选择轴
initColumn(curMonth) {
let years = []
let months = []
let days = []
let hours = []
let minutes = []
let seconds = []
for (let i = 1990; i <= 2099; i++) {
years.push(i + '')
}
for (let i = 1; i <= 12; i++) {
if (i < 10) {
i = "0" + i;
}
months.push(i + '')
}
if (curMonth == 1 || curMonth == 3 || curMonth == 5 || curMonth == 7 || curMonth == 8 || curMonth == 10 || curMonth == 12) {
for (let i = 1; i <= 31; i++) {
if (i < 10) {
i = "0" + i;
}
days.push(i + '')
}
}
if (curMonth == 4 || curMonth == 6 || curMonth == 9 || curMonth == 11) {
for (let i = 1; i <= 30; i++) {
if (i < 10) {
i = "0" + i;
}
days.push(i + '')
}
}
if (curMonth == 2) {
days=this.setFebDays()
}
for (let i = 0; i <= 23; i++) {
if (i < 10) {
i = "0" + i;
}
hours.push(i + '')
}
for (let i = 0; i <= 59; i++) {
if (i < 10) {
i = "0" + i;
}
minutes.push(i + '')
}
for (let i = 0; i <= 59; i++) {
if (i < 10) {
i = "0" + i;
}
seconds.push(i + '')
}
this.setData({
years,
months,
days,
hours,
minutes,
seconds
})
},
/**
* 列改变时触发
*/
bindPickerColumnChange: function(e) {
//获取年份 用于计算改年的2月份为平年还是闰年
if (e.detail.column == 0 && this.properties.format != 'HH:mm:ss') {
let chooseYear = this.data.multiArray[e.detail.column][e.detail.value];
this.setData({
chooseYear
})
if (this.data.curMonth == '02' || this.data.chooseMonth == '02') {
this.setFebDays()
}
}
//当前第二为月份时需要初始化当月的天数
if (e.detail.column == 1 && this.properties.format != 'HH:mm:ss') {
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月份天数
this.setFebDays()
}
}
let data = {
multiArray: this.data.multiArray,
multiIndex: this.data.multiIndex
};
data.multiIndex[e.detail.column] = e.detail.value;
this.setData(data);
},
//计算二月份天数
setFebDays() {
let year = parseInt(this.data.chooseYear);
let temp = [];
if (year % (year % 100 ? 4 : 400) ? false : true) {
for (let i = 1; i <= 29; i++) {
if (i < 10) {
i = "0" + i;
}
temp.push("" + i);
}
this.setData({
['multiArray[2]']: temp,
chooseMonth: '02'
});
} else {
for (let i = 1; i <= 28; i++) {
if (i < 10) {
i = "0" + i;
}
temp.push("" + i);
}
this.setData({
['multiArray[2]']: temp,
chooseMonth: '02'
});
}
return temp;
}
},
})
wxss
.view-body {
display: flex;
align-items: center;
padding: 4% 0%;
border-bottom: 1px solid #eee;
}
.item-key {
font-size: 30rpx;
color: #666;
width: 25%;
}
.item-value {
flex-grow: 1;
font-size: 31rpx;
position: relative;
margin-left: 3%;
}
.img-arrow {
width: 45rpx;
height: 45rpx;
padding-right: 10rpx;
position: absolute;
top: 50%;
transform: translateY(-50%);
right: 5rpx;
}
使用
在你页面中的json中添加引用,路径根据你的实际工程目录来写。
{
"usingComponents": {
"DateTimePicker": "/components/datetimepicker/datetimepicker"
}
}
wxml中添加
<DateTimePicker title='选择时间' isRequired='true' bind:dateTimePicker='onDateTimePicker' name='time' format='yyyy-MM-dd HH:mm:ss'/>
说明
- title:表单组件的名称
- isRequired:是否必填项
- dateTimePicker:为选中确认回调
- name:为表单点击 form 表单中 form-type 为 submit 的 button 组件时,会将表单组件中的 value 值进行提交,需要在表单组件中加上 name 来作为 key
- format:时间格式化参数 支持:‘yyyy-MM-dd HH:mm:ss’,‘HH:mm:ss’,‘yyyy-MM-dd HH:mm’,‘yyyy-MM-dd’ 四种
开发者可以根据自己的需求调整组件样式
建议在picker列加上中文,这样更加直观
老哥。用markdown写下文章。这个代码 不太容易理解
可以改为:
value= `${curYear}-${showMonth}-${showDay}`
然后后面判断的代码有点冗余了,可以简化下。只是单纯提个建议哈。 老哥牛逼
已取用,非常感谢
老哥,你这个是官方picker的升级版,建议把picker的一些字段加入,比如disabled等
disabled: { type: Boolean },
if
(curMonth == 2) {
days =
this
.setFebDays();
}
initColumn方法在2月时候没有天数,可以把setFebDays 天数返回
// initColumn 方法
if (curMonth == 2) {
days = this.setFebDays();
}
// setFebDays 方法
setFebDays() {
let year = parseInt(this.data.chooseYear);
let temp = [];
if (!(year % (year % 100 ? 4 : 400))) {
for (let i = 1; i <= 29; i++) {
if (i < 10) {
i = "0" + i;
}
temp.push("" + i);
}
this.setData({
["multiArray[2]"]: temp,
chooseMonth: "02"
});
} else {
for (let i = 1; i <= 28; i++) {
if (i < 10) {
i = "0" + i;
}
temp.push("" + i);
}
this.setData({
["multiArray[2]"]: temp,
chooseMonth: "02"
});
}
return temp;
},
向大佬学习