时间控件,精确到分,能随着上级时间的改变而改变(在其他大佬的组件基础上进行二次封装):
<view>
<picker disabled="{{disabled}}" mode="multiSelector" bindchange="pickerChange" bindcolumnchange="pickerColumnChange" bindcancel ="pickerCancel" value="{{pickerIndex}}" range="{{pickerArray}}" range-key="{{'name'}}">
<view style='font-size:.7rem;background-color: #F8F8FF;line-height: 40px;padding:0px 10px;width:100%;text-align:left' >
<button class="chooseTime">选择预约时间</button>
</view>
</picker>
</view>
//代码中涉及小程序的生命周期,具体可以参照 https://www.cnblogs.com/nosqlcoco/p/wxsmallcycle.html
// component/pickerYMDHM.js
Component({
/**
* 组件的属性列表
*/
properties: {
date: { // 属性名
type: null, // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
value: null // 属性初始值(可选),如果未指定则会根据类型选择一个
},
startDate: {
type: null, // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
value: null // 属性初始值(可选),如果未指定则会根据类型选择一个
},
endDate: {
type: null, // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
value: null // 属性初始值(可选),如果未指定则会根据类型选择一个
},
disabled: {
type: null, // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
value: false // 属性初始值(可选),如果未指定则会根据类型选择一个
},
placeholder: {
type: null, // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
value: null // 属性初始值(可选),如果未指定则会根据类型选择一个
}
},
/**
* 组件的初始数据
*/
data: {
pickerArray: [],//日期控件数据list
pickerIndex: [],//日期控件选择的index
chooseIndex: [],//日期控件确认选择的index
chooseArray: [],//日期控件确认选择后的list
dateString: '',//页面显示日期
startMonth: 0,//用来判断是否改变数组的变量
startDay: 0,//用来判断是否改变数组的变量
startHour: 0,//用来判断是否改变数组的变量
},
/**
* 组件的方法列表
*/
methods: {
_onInit() {
let date = new Date();
if (this.data.date != null) {
let str = this.data.date;
str = str.replace(/-/g, "/");
date = new Date(str);
}
let pickerArray = this.data.pickerArray;
//默认选择3年内
let year = [];
console.log('date.getFullYear()')
console.log(date.getFullYear())
let startDate = date.getFullYear() - 1;
let endDate = date.getFullYear() + 1;
if (this.data.startDate != null) {
//如果存在开始时间,则默认设置结束时间为2099
startDate = this.data.startDate;
endDate = 2099;
}
if (this.data.endDate != null && this.data.startDate == null) {
//如果存在结束时间,不存在开始时间 则默认设置开始时间为1900
endDate = this.data.endDate;
startDate = 1900;
}
if (this.data.endDate != null && this.data.startDate != null) {
endDate = this.data.endDate;
}
if (startDate > date.getFullYear() || endDate < date.getFullYear()) {
this.setData({
dateString: "默认日期不在时间范围内"
})
return;
}
for (let i = startDate; i <= endDate; i++) {
year.push({ id: i, name: i + "年" });
}
//开始月份
let startMonth = new Date().getMonth() + 1;
// console.log(year);
let month = [];
//开始月份
for (let i = startMonth; i <= 12; i++) {
month.push({ id: i, name: i + "月" });
}
// console.log(month);
let dayNum = this.getDayNum(new Date().getFullYear(), startMonth)
let day = [];
// debugger
let startDay = new Date().getDate();
for (let i = startDay; i <= dayNum; i++) {
day.push({ id: i, name: i + "日" });
}
let time = [];
let startHour = new Date().getHours()
for (let i = startHour; i <= 23; i++) {
if (i < 10) {
time.push({ id: i, name: i + "时" });
} else {
time.push({ id: i, name: i + "时" });
}
}
//保存数据
this.setData({
startMonth: startMonth,
startDay: startDay,
startHour: startHour,
})
// console.log(time);
let division = [];
let startMinute = new Date().getMinutes()
for (let i = startMinute; i <= 59; i++) {
if (i < 10) {
division.push({ id: i, name: i + "分" });
} else {
division.push({ id: i, name: i + "分" });
}
}
// console.log(division);
pickerArray[0] = year;
pickerArray[1] = month;
pickerArray[2] = day;
pickerArray[3] = time;
pickerArray[4] = division;
console.log("打印pickerArray")
console.log(pickerArray)
let mdate = {
date: date,
year: date.getFullYear() + '',
month: date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1 + '',
day: date.getDate() < 10 ? '0' + date.getDate() : date.getDate() + '',
time: date.getHours() < 10 ? '0' + date.getHours() : date.getHours() + '',
division: date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes() + ''
}
mdate.dateString = mdate.year + '-' + mdate.month + '-' + mdate.day + ' ' + mdate.time + ':' + mdate.division;
this.setData({
pickerArray,
pickerIndex: [date.getFullYear() - startDate, date.getMonth(), date.getDate() - 1, date.getHours(), date.getMinutes()],
chooseIndex: [date.getFullYear() - startDate, date.getMonth(), date.getDate() - 1, date.getHours(), date.getMinutes()],
chooseArray: pickerArray,
dateString: this.data.placeholder != null ? this.data.placeholder : mdate.dateString
})
// console.log(date);
//设置placeholder属性后 初始化不返回日期
if (this.data.placeholder == null) {
this.triggerEvent('onPickerChange', mdate);
}
console.log("mdate")
console.log(mdate)
},
gettime() {
let that = this;
let date = new Date();
// 设置循环数据 years,months,days
let year = date.getFullYear();
let years = [];
years.push(year)
let month = (date.getMonth() + 1) < 9 ? '0' + (date.getMonth() + 1) : (date.getMonth() + 1)
let endMonth = Number(month) + 1 > 9 ? Number(month) + 1 : '0' + (Number(month) + 1)
let day = (date.getDate()) < 9 ? '0' + (date.getDate()) : (date.getDate())
let hour = date.getHours() < 9 ? '0' + date.getHours() : date.getHours()
let minute = date.getMinutes() < 9 ? '0' + date.getMinutes() : date.getMinutes()
let today = year + '-' + month + '-' + day;
let end = year + '-' + endMonth + '-' + day
let currentDate = year + '-' + month + '-' + day
return currentDate
},
/**
*
* 获取本月天数
* @param {number} year
* @param {number} month
* @param {number} [day=0] 0为本月0最后一天的
* @returns number 1-31
*/
_getNumOfDays(year, month, day = 0) {
return new Date(year, month, day).getDate()
},
//picker 组件的改变事件
pickerChange: function (e) {
// console.log('picker发送选择改变,携带值为', e.detail.value)
let indexArr = e.detail.value;
const year = this.data.pickerArray[0][indexArr[0]].id;
const month = this.data.pickerArray[1][indexArr[1]].id;
const day = this.data.pickerArray[2][indexArr[2]].id;
const time = this.data.pickerArray[3][indexArr[3]].id;
const division = this.data.pickerArray[4][indexArr[4]].id;
let date = {
date: new Date(year + '-' + month + '-' + day + ' ' + time + ':' + division),
year: year + '',
month: month < 10 ? '0' + month : month + '',
day: day < 10 ? '0' + day : day + '',
time: time < 10 ? '0' + time : time + '',
division: division < 10 ? '0' + division : division + ''
}
date.dateString = date.year + '-' + date.month + '-' + date.day + ' ' + date.time + ':' + date.division;
this.setData({
chooseIndex: e.detail.value,
chooseArray: this.data.pickerArray,
dateString: date.dateString
})
// 父组件监听的动作,类似于vue 中子组件发出的 emit
this.triggerEvent('onPickerChange', date);
},
//列改变
pickerColumnChange: function (e) {
if (e)
// console.log('修改的列为', e.detail.column, ',值为', e.detail.value);
var data = {
pickerArray: this.data.pickerArray,
pickerIndex: this.data.pickerIndex
};
data.pickerIndex[e.detail.column] = e.detail.value;
//改变年份
if (e.detail.column == 0) {
let nowYear = data.pickerArray[0][data.pickerIndex[0]].id
let nowMonth = data.pickerArray[1][data.pickerIndex[1]].id
let month = []
let day = []
let hour = []
let minute = []
if (e.detail.value == 0) {
//还是当前的年份
this._onInit();//再调用一遍初始化
} else {
//要自己设置
//月份
for (let i = 1; i <= 12; i++) {
month.push({ id: i, name: i + "月" });
}
//天数
// 30
let dayNum = this.getDayNum(nowYear, 1)
for (let i = 1; i <= dayNum; i++) {
day.push({ id: i, name: i + "日" });
}
//小时
for (let i = 1; i <= 23; i++) {
hour.push({ id: i, name: i + "时" });
}
//分钟
for (let i = 1; i < 60; i++) {
minute.push({ id: i, name: i + "分" });
}
data.pickerArray[1] = month;
data.pickerArray[2] = day;
data.pickerArray[3] = hour;
data.pickerArray[4] = minute;
}
}
//改变月份
if (e.detail.column == 1) {
let nowYear = data.pickerArray[0][data.pickerIndex[0]].id
let nowMonth = data.pickerArray[1][data.pickerIndex[1]].id
let dayNum = this.getDayNum(nowYear, nowMonth)
console.log('打印dateNum890')
console.log(dayNum) //
let day = [];
let hour = []
let minute = []
let startDay = new Date().getDate();
///相同才还原
if (e.detail.value == 0 && nowMonth == this.data.startMonth) {
//还原
for (let i = startDay; i <= dayNum; i++) {
day.push({ id: i, name: i + "日" });
}
let startHour = new Date().getHours()
for (let i = startHour; i <= 23; i++) {
if (i < 10) {
hour.push({ id: i, name: i + "时" });
} else {
hour.push({ id: i, name: i + "时" });
}
}
// console.log(time);
let startMinute = new Date().getMinutes()
for (let i = startMinute; i <= 59; i++) {
if (i < 10) {
minute.push({ id: i, name: i + "分" });
} else {
minute.push({ id: i, name: i + "分" });
}
}
} else {
//设置
for (let i = 1; i <= dayNum; i++) {
day.push({ id: i, name: i + "日" });
}
for (let i = 1; i <= 23; i++) {
if (i < 10) {
hour.push({ id: i, name: i + "时" });
} else {
hour.push({ id: i, name: i + "时" });
}
}
// console.log(time);
for (let i = 1; i <= 59; i++) {
if (i < 10) {
minute.push({ id: i, name: i + "分" });
} else {
minute.push({ id: i, name: i + "分" });
}
}
}
if (dayNum < data.pickerIndex[2] + 1) {
data.pickerIndex[2] = dayNum - 1;
}
//赋值
data.pickerArray[2] = day;
data.pickerArray[3] = hour;
data.pickerArray[4] = minute;
}
//改变天
if (e.detail.column == 2) {
let hour = []
let minute = []
let nowDay = data.pickerArray[2][data.pickerIndex[2]].id
//小时
if (e.detail.value == 0 && nowDay == this.data.startDay) {
console.log("是否还原了")
let startHour = new Date().getHours()
for (let i = startHour; i <= 23; i++) {
if (i < 10) {
hour.push({ id: i, name: i + "时" });
} else {
hour.push({ id: i, name: i + "时" });
}
}
// console.log(time);
let startMinute = new Date().getMinutes()
for (let i = startMinute; i <= 59; i++) {
if (i < 10) {
minute.push({ id: i, name: i + "分" });
} else {
minute.push({ id: i, name: i + "分" });
}
}
} else {
for (let i = 1; i <= 23; i++) {
hour.push({ id: i, name: i + "时" });
}
//分钟
for (let i = 1; i < 60; i++) {
minute.push({ id: i, name: i + "分" });
}
}
data.pickerArray[3] = hour;
data.pickerArray[4] = minute;
}
//改变小时
if (e.detail.column == 3) {
let minute = []
let nowHour = data.pickerArray[3][data.pickerIndex[3]].id
//小时
if (e.detail.value == 0 && nowHour == this.data.startHour) {
console.log("是否还原了")
// console.log(time);
let startMinute = new Date().getMinutes()
for (let i = startMinute; i <= 59; i++) {
if (i < 10) {
minute.push({ id: i, name: i + "分" });
} else {
minute.push({ id: i, name: i + "分" });
}
}
} else {
//分钟
for (let i = 1; i < 60; i++) {
minute.push({ id: i, name: i + "分" });
}
}
data.pickerArray[4] = minute;
}
this.setData(data);
},
//获取本月天数的
getDayNum(year, month) {
let dayNum = 0
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
dayNum = 31
return dayNum
} else if (month == 4 || month == 6 || month == 9 || month == 11) {
dayNum = 30
return dayNum
} else if (month == 2) {
//二月份
if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {
//计算闰年
dayNum = 29
return dayNum
} else {
dayNum = 28
return dayNum
}
}
},
pickerCancel: function (e) {
// console.log("取消");
this.setData({
pickerIndex: this.data.chooseIndex,
pickerArray: this.data.chooseArray
})
},
},
// 以下是旧式的定义方式,可以保持对 <2.2.3 版本基础库的兼容
ready() {
console.log('进入ready外层节点=', this.data.date);
this._onInit();
},
// 以下为新方法 >=2.2.3
lifetimes: {
ready() {
console.log('进入ready节点=', this.data.date);
this._onInit();
}
}
})
样式是根据自己的需要,可以自行更改:
.chooseTime{
width:240rpx;
height:70rpx;
line-height:70rpx;
border-radius:40rpx;
background:#ff9800;
color:white;
font-size:28rpx;
border:none;
position:fixed;
/* bottom:60rpx; */
left:120rpx;
bottom:88rpx;
}
在页面中使用:
首先,在页面的 .json 文件中:
{
"usingComponents": {
"newPicker": "/component/newPicker"
}
}
newPicker 是在页面中使用时用的名字,/component/newPicker 是组件所在的文件路径
在页面中:
<pickerYMDHM placeholder = "{{placeholder}}" date = "{{date2}}" disabled = "{{disabled}}" bind:onPickerChange="onPickerChange2" startDate="{{startDate}}" endDate="{{endDate}}" >
</pickerYMDHM>