这种时间选择区间 应该很常见 上代码(小程序原生实现)
wxjs
var app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
remind_pull: true,
s_time: '', //选择开始时间 s_time 在请求数据时 加了 "00:00:00"
e_time: '', //选择结束时间 e_time 在请求数据时加了 "23:59:59"
startDialog: false,//开始时间选择picker显隐
endDialog: false,//结束时间选择picker显隐
years: [],
months: [],
days: [],
year: 0,
month: 0,
day: 0,
value: [8, 1, 1]
},
openStartDialog() {
this.setData({
startDialog: true
})
},
openEndDialog() {
this.setData({
endDialog: true
})
},
closeStart() {
this.setData({
startDialog: false
})
},
selectedStime() {
// 如果没有滑动事件 肯定没有触发 bindChangeStart 事件
// 那就加个当前时间
const date = new Date()
const nowYear = date.getFullYear()
const nowMonth = date.getMonth() + 1
const nowDay = date.getDate()
let curStartTime = nowYear + "-" + nowMonth + "-" + nowDay
if (!this.data.s_time) {
this.setData({
s_time: curStartTime
})
}
this.setData({
startDialog: false
})
},
closeEnd() {
this.setData({
endDialog: false
})
},
selectedEtime() {
// 如果没有滑动事件 肯定没有触发 bindChangeEnd 事件
// 那也加个当前时间
const date = new Date()
const nowYear = date.getFullYear()
const nowMonth = date.getMonth() + 1
const nowDay = date.getDate()
let curEndTime = nowYear + "-" + nowMonth + "-" + nowDay
if (!this.data.e_time) {
this.setData({
e_time: ''
})
}
// 在这写你要刷新数据的方法名,比如下面的方法
this.getOrderList() // 刷新
this.setData({
endDialog: false
})
},
bindChangeStart(e) {
const valIndex = e.detail.value
let yarr = this.data.years
let marr = this.data.months
let darr = this.data.days
let year = yarr[valIndex[0]]
let month = marr[valIndex[1]]
let day = darr[valIndex[2]]
// 滚动时再动态 通过年和月获取 这个月下对应有多少天
this.getStartTime(year, month, day)
},
bindChangeEnd(e) {
const valIndex = e.detail.value
let yarr = this.data.years
let marr = this.data.months
let darr = this.data.days
let year = yarr[valIndex[0]]
let month = marr[valIndex[1]]
let day = darr[valIndex[2]]
// 滚动时再动态 通过年和月获取 这个月下对应有多少天
this.getEndTime(year, month, day)
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
// 初始化时间
this.initDatas()
},
initDatas() {
// 获取当前年月
const date = new Date()
const nowYear = date.getFullYear()
const nowMonth = date.getMonth() + 1
const nowDay = date.getDate()
let s_time = nowYear + "-" + nowMonth + "-" + nowDay
let daystart = new Date(s_time.replace(/-/g, "/")).getTime()
this.setData({
year: nowYear,
month: nowMonth,
day: nowDay,
years: [],
months: [],
s_time: nowYear + '-' + nowMonth + '-' + nowDay,
e_time: "",
daystart: daystart
})
let yearsarr = []
let monthsarr = []
for (let i = 2022; i <= nowYear + 10; i++) {
yearsarr.push(i)
}
// 设置月份列表
for (let i = 1; i <= 12; i++) {
monthsarr.push(i)
}
this.setData({
years: yearsarr,
months: monthsarr,
})
// 初始化当前年月
if (this.data.startDialog) {
this.getStartTime(nowYear, nowMonth, nowDay)
} else {
this.getEndTime(nowYear, nowMonth, nowDay)
}
},
getStartTime(year, month, day) {
console.log(year, month, day)
let s_time = year + "-" + month + "-" + day
let daystart = new Date(s_time.replace(/-/g, "/")).getTime()
this.setData({
s_time: s_time,
e_time: "",
daystart: daystart
})
let daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
let dayNum = 0
// 通过年和月获取这个月份下有多少天
if (month === 2) { // 闰年
dayNum = ((year % 4 === 0) && ((year % 100) !== 0)) || (year % 400 === 0) ? 29 : 28
} else {
dayNum = daysInMonth[month - 1]
}
let daysarr = []
for (let i = 1; i <= dayNum; i++) {
daysarr.push(i)
}
this.setData({
days: daysarr
})
// 初始 选中年月日对应下标
let yearIdx = 0
let monthIdx = 0
let dayIdx = 0
// 获取滚动后 年月日对应的下标
this.data.years.map((v, idx) => {
if (v === year) {
yearIdx = idx
}
})
this.data.months.map((v, idx) => {
if (v === month) {
monthIdx = idx
}
})
this.data.days.map((v, idx) => {
if (v === day) {
dayIdx = idx
}
})
// 重置滚动后 年月日 的下标
let valuearr = [yearIdx, monthIdx, dayIdx]
this.setData({
value: valuearr
})
// 赋值年月日
let yeartext = this.data.years[yearIdx]
let monthtext = this.data.years[monthIdx]
let daytext = this.data.years[dayIdx]
this.setData({
year: yeartext,
month: monthtext,
day: daytext
})
},
tipToStartTime() {
wx.showToast({
title: '请先选择开始时间',
icon: 'none'
})
},
getEndTime(year, month, day) {
let e_time = year + "-" + month + "-" + day
this.setData({
e_time
})
let daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
let dayNum = 0
// 通过年和月获取这个月份下有多少天
if (month === 2) { // 闰年
dayNum = ((year % 4 === 0) && ((year % 100) !== 0)) || (year % 400 === 0) ? 29 : 28
} else {
dayNum = daysInMonth[month - 1]
}
let daysarr = []
for (let i = 1; i <= dayNum; i++) {
daysarr.push(i)
}
this.setData({
days: daysarr
})
// 初始 选中年月日对应下标
let yearIdx = 0
let monthIdx = 0
let dayIdx = 0
// 获取滚动后 年月日对应的下标
this.data.years.map((v, idx) => {
if (v === year) {
yearIdx = idx
}
})
this.data.months.map((v, idx) => {
if (v === month) {
monthIdx = idx
}
})
this.data.days.map((v, idx) => {
if (v === day) {
dayIdx = idx
}
})
// 重置滚动后 年月日 的下标
let valuearr = [yearIdx, monthIdx, dayIdx]
this.setData({
value: valuearr
})
// 赋值年月日
let yeartext = this.data.years[yearIdx]
let monthtext = this.data.years[monthIdx]
let daytext = this.data.years[dayIdx]
this.setData({
year: yeartext,
month: monthtext,
day: daytext
})
let dayend = new Date(this.data.e_time.replace(/-/g, "/")).getTime()
if (this.data.daystart <= dayend) {
//这里写如果时间区间选择正确时 处理的逻辑
} else {
wx.showToast({
title: '请选择正确的时间区间',
icon: 'none',
duration: 1000,
mask: true
})
this.setData({
e_time: ""
})
}
})
wxml
// 开始时间
<view class="dialog" wx:if="{{startDialog}}">
<view class="dialog-con">
<view class="dialog-top">
<text>选择开始时间</text>
<image bindtap="closeStart" class="closeDialog" src="/images/close-coupon2.png"></image>
</view>
<view class="dialog-bottom">
<view class="dialog-bottom-con">
<picker-view indicator-style="height: 50px;" style="width: 100%; height: 300px;" value="{{value}}" bindchange="bindChangeStart">
<picker-view-column>
<view wx:for="{{years}}" wx:key="item" style="line-height: 50px; text-align: center;">{{item}}年</view>
</picker-view-column>
<picker-view-column>
<view wx:for="{{months}}" wx:key="item" style="line-height: 50px; text-align: center;">{{item}}月
</view>
</picker-view-column>
<picker-view-column>
<view wx:for="{{days}}" wx:key="item" style="line-height: 50px; text-align: center;">{{item}}日</view>
</picker-view-column>
</picker-view>
</view>
<view class="btn" bindtap="selectedStime" style="margin-top: 40rpx;">确定</view>
</view>
</view>
</view>
// 结束时间
<view class="dialog" wx:if="{{endDialog}}">
<view class="dialog-con">
<view class="dialog-top">
<text>选择结束时间</text>
<image bindtap="closeEnd" class="closeDialog" src="/images/close-coupon2.png"></image>
</view>
<view class="dialog-bottom">
<view class="dialog-bottom-con">
<picker-view indicator-style="height: 50px;" style="width: 100%; height: 300px;" value="{{value}}" bindchange="bindChangeEnd">
<picker-view-column>
<view wx:for="{{years}}" wx:key="item" style="line-height: 50px; text-align: center;">{{item}}年</view>
</picker-view-column>
<picker-view-column>
<view wx:for="{{months}}" wx:key="item" style="line-height: 50px; text-align: center;">{{item}}月
</view>
</picker-view-column>
<picker-view-column>
<view wx:for="{{days}}" wx:key="item" style="line-height: 50px; text-align: center;">{{item}}日</view>
</picker-view-column>
</picker-view>
</view>
<view class="btn" bindtap="selectedEtime" style="margin-top: 40rpx;">确定</view>
</view>
</view>
</view>
wxss
page {
background-color: #fff;
}
.page_main {
position: relative;
width: 100%;
height: 100%;
}
.dialog {
width: 100%;
position: fixed;
top: 0;
left: 0;
height: 100%;
background-color: rgba(0, 0, 0, 0.6);
z-index: 9;
}
.dialog-con {
width: 100%;
min-height: 600rpx;
max-height: 1000rpx;
position: absolute;
bottom: 0;
left: 0;
background-color: #fff;
border-top-right-radius: 20rpx;
border-top-left-radius: 20rpx;
}
.dialog-top {
width: 100%;
height: 88rpx;
text-align: center;
font-size: 36rpx;
font-family: PingFang SC;
font-weight: bold;
line-height: 88rpx;
color: rgba(50, 50, 51, 1);
position: relative;
}
.closeDialog {
position: absolute;
width: 36rpx;
height: 36rpx;
top: 26rpx;
right: 32rpx;
}
.dialog-bottom {
width: 100%;
padding: 20rpx 60rpx 72rpx 70rpx;
box-sizing: border-box;
}
.dialog-bottom-con {
height: 500rpx;
overflow-y: scroll;
}
.dialog-bottom-li {
width: 100%;
background: #F8F8FA;
border-radius: 8rpx;
padding: 30rpx;
box-sizing: border-box;
margin-bottom: 16rpx;
position: relative;
}
.dialog-bottom-li.active {
border: 2rpx solid #028B7B;
}
.dialog-bottom-li-tit {
font-size: 32rpx;
font-family: PingFang SC;
font-weight: bold;
line-height: 44rpx;
color: #333333;
margin-bottom: 8rpx;
}
.dialog-bottom-li-img {
width: 78rpx;
height: 44rpx;
position: absolute;
bottom: -2rpx;
right: -2rpx;
}
.dialog-bottom-li-txt {
font-size: 24rpx;
font-family: PingFang SC;
font-weight: 400;
line-height: 34rpx;
color: #999999;
}
.dialog-bottom-li-tit.active {
color: #028B7B;
}
.dialog-bottom-li-txt.active {
color: #028B7B;
}