怎么用uni-popup实现菜鸟上门取件时间选择器(uni-popup,开发技术)

时间:2024-05-02 05:11:00 作者 : 石家庄SEO 分类 : 开发技术
  • TAG :

兼容

因为目前我的项目只用到这三端,其他的都还没测,所以兼容不保证

  • 支付宝小程序开发者工具popup弹出来会直接滚到最顶部,显示异常,但真机上面没问题,可以不用管

环境兼容支付宝小程序✔微信小程序✔H5✔

菜鸟上门时间选择器

怎么用uni-popup实现菜鸟上门取件时间选择器

需求分析:

1、弹窗从底部弹出

  • 点击蒙层不可关闭

  • 弹窗header左侧title , 右侧关闭按钮

2、左侧日期选择器

  • 显示近3天日期

  • 显示(今天、明天、周一、周二等)

3、右侧时间选择器

  • 可选时间可配置

  • 过期时间显示 “已过期”

  • 选中效果

  • 当前已无可选时间,应该删除今天日期,只可以选未来日期

代码实现:

1.popup弹窗

先做一下基础布局,简单的分成上左右三大块,并做一些基础的配置

怎么用uni-popup实现菜鸟上门取件时间选择器

<template>
<uni-popup
mask-background-color="rgba(0,0,0,.8)"
ref="datePickerPop"
type="bottom"
background-color="#fff"
:is-mask-click="false"
>
<viewclass="date_pop">
<viewclass="popup_header">
<viewclass="pop_title">请选择取件时间</view>
<viewclass="pop-close"@click="handleClose('datePop')"/>
</view>
<!--日期-->
<viewclass="date_con">
<scroll-viewscroll-y="true"class="date_box">
</scroll-view>
<!--时间-->
<scroll-viewscroll-y="true"class="time_box">
</scroll-view>
</view>
</view>
</uni-popup>
</template>
<script>
exportdefault{
name:'TimePicker',
props:{
visible:{
required:true,
default:false
}
},
watch:{
visible(newVal){
if(newVal){
if(!this.selectedDate.date_zh){
this.selectedDate=this.effectRecentDate[0];
}
this.$refs.datePickerPop.open();
}else{
this.$refs.datePickerPop.close();
}
}
},
methods:{
handleClose(){
this.$emit('update:visible',false);
},
}
};
</script>
<stylescopedlang="scss">
.date_pop{
padding:0;
height:750rpx;
.popup_header{
display:flex;
align-items:center;
justify-content:space-between;
box-sizing:border-box;
padding:60rpx40rpx;
.pop_title{
font-weight:bold;
font-size:32rpx;
width:90%;
}
.pop-close{
width:60rpx;
height:60rpx;
background:url('~@/static/images/close.png');
background-size:22rpx;
background-position:center;
background-repeat:no-repeat;
}
}
.date_con{
font-size:28rpx;
position:relative;
height:600rpx;
}
.date_box{
position:absolute;
top:0;
left:0;
width:40%;
height:100%;
background:#f7f7f9;
overflow-y:scroll;
.date_item{
padding:040rpx;
line-height:100rpx;
}
}
.time_box{
position:absolute;
top:0;
right:0;
width:60%;
height:100%;
}
.date_active{
background:#fff;
}
}
</style>

2.日期+时间选择器

按照需求我重新设计了一下功能及交互

日期选择器

  • 日期可配置,支持显示最近n天日期

  • 显示今天、明天、后台及工作日

  • 默认选中当日(今天)

时间选择器

基础功能

  • 删除过期时间

  • 今日所有可选日期都过期之后删除日期选框(今天)选项

  • 选中时间后面打钩,并关闭弹窗

可选功能

  • 显示已过期时间 (逻辑几个版本之前已经删除了,现在只剩类名,需要的同学可以大概看下代码把它加上或者评论区留个言我把给你找找代码 , 功能样式就类似菜鸟)

  • 直接删除已过期时间

核心逻辑:

1、生成左侧日期列表

//生成时间选择器最近n天的时间
/
@n{Number}:生成的天数

/
setRecentData(n){
constoneDaySeconds=60
10006024;
consttoday=+newDate();
letlist=[];
for(leti=0;i&lt;n;i++){
letformatTime=this.formatTime_zh(today+oneDaySeconds*i);
list.push({
...formatTime,
week:i==0?'今天':i==1?'明天':formatTime.week
});
}
//设置一下默认选中日期
this.selectedDate=list[0];
returnlist;
},
//时间处理函数
formatTime_zh(date){
date=newDate(date);
constyear=date.getFullYear();
constmonth=date.getMonth()+1;
constday=date.getDate();
constweekDay=date.getDay();
constformatNumber=(n)=&gt;{
n=n.toString();
returnn[1]?n:'0'+n;
};
constnumToTxt=['周日','周一','周二','周三','周四','周五','周六'];
return{
date_zh:${formatNumber(month)}月${formatNumber(day)}日,
date_en:${year}/${formatNumber(month)}/${formatNumber(day)},
week:numToTxt[weekDay]
};
},

最终数据格式如图:

怎么用uni-popup实现菜鸟上门取件时间选择器

2、判断时间有没有过期

因为考虑到取件没有那么快,至少要提前半小时下单,所以就有了下面的逻辑(我这里是90分钟)

  • 传入 09:00-10:00 格式时间区间

  • 截取过期时间, 和当前时间做对比

  • 判断已过期 、即将过期 、未过期

/
@return{Number}1:已过期,2:即将过期,3:未过期
@time{String}09:00-10:00
/
checkRemainingMinute(time){
if(!time)return;
//过期时间
constoutTime=time.toString().split('-')[1];
//这里兼容一下iphone,iphone不支持yyyy-mm-ddhh:mm格式时间,分隔符换为/
constfullYearDate=formatMinute(newDate(),'/');
constnow=newDate(fullYearDate);
constdateTime=this.currentDate+''+outTime;
constcheck=newDate(dateTime);
constdifference=check-now;
constminutes=difference/(1000
60);
//minutes&lt;=0:已过期--&gt;1
//minutes&lt;=90:即将过期--&gt;2
//minutes&gt;0:未过期--&gt;3
returnminutes&lt;=0?1:minutes&lt;=90?2:3;
}
/

@descriptionyyyy-mm-ddhh:mm
@authorwangxinu
@export
@param{}cent
@returns
/
formatMinute:(date,separator='-')=&gt;{
date=newDate(date);
constyear=date.getFullYear();
constmonth=date.getMonth()+1;
constday=date.getDate();
consthour=date.getHours();
constminute=date.getMinutes();
constsecond=date.getSeconds();
constformatNumber=(n)=&gt;{
n=n.toString();
returnn[1]?n:'0'+n;
};
return${formatNumber(year)}${separator}${formatNumber(month)}${separator}${formatNumber( day, )}${formatNumber(hour)}:${formatNumber(minute)};
},

3、通过计算属性获取有效时间(即右侧列表展示即将过期的和未过期的时间)

data(){
return{
appointment:[
'08:00-09:00',
'09:00-10:00',
'10:00-11:00',
'11:00-12:00',
'12:00-13:00',
'13:00-14:00',
'14:00-15:00',
'15:00-16:00',
'16:00-17:00',
'17:00-18:00',
'18:00-19:00',
'19:00-20:00'
]
}
},
computed:{
//有效取件时间
effectAppointmentTime(){
//取件时间列表
constappointment=this.appointment;
//未来日期返回全部
if(this.selectedDate.date_en!=this.currentDate){
returnappointment;
}
//当日只返回有效时间
letlist=appointment.filter((item)=&gt;this.checkRemainingMinute(item)!=1);
//当天取件时间长度&gt;0添加立即上门
if(list.length&gt;0){
list.unshift('立即上门');
}
returnlist;
}
},

4、通过计算属性获取有效日期

computed:{
//有效日期
effectRecentDate(){
//查看有效时间列表
consteffectAppointmentTime=this.effectAppointmentTime;
//当日取件时间全部失效
if(effectAppointmentTime.length==0){
//删除(今日)
this.recentDateList.splice(0,1);
//修改默认选中日期
this.selectedDate=this.recentDateList[0];
returnthis.recentDateList;
}else{
returnthis.recentDateList;
}
},
},

5、日期或时间选中函数

 //时间选择器修改函数
timeChange(date,type){
constdateList=this.recentDateList;
if(type==='date'){
//选择日期
this.selectedDate=date;
this.selectedTime='';
}else{
//选择时间
this.selectedTime=date;
if(this.selectedDate.date_zh==''){
this.selectedDate=dateList[0];
}
this.handleClose();
this.$emit('selectTime',this.selectedDate,this.selectedTime);
}
},

源码及使用

使用:

<template>
<divclass="page">
<button@click="timePicker_visible=true"type="primary">打开弹窗</button>
<TimePicker:visible.sync="timePicker_visible"@selectTime="selectTime"/>
</div>
</template>
<script>
importTimePickerfrom'./components/TimePicker';
exportdefault{
name:'test',
components:{TimePicker},
mixins:[],
props:{},
data(){
return{
timePicker_visible:false
};
},
methods:{
selectTime(date,time){
console.log('date',date)
console.log('time',time)
}
}
};
</script>

源码:

<template>
<uni-popup
mask-background-color="rgba(0,0,0,.8)"
ref="datePickerPop"
type="bottom"
background-color="#fff"
:is-mask-click="false"
>
<viewclass="date_pop">
<viewclass="popup_header">
<viewclass="pop_title">请选择取件时间</view>
<viewclass="pop-close"@click="handleClose('datePop')"/>
</view>
<!--日期-->
<viewclass="date_con">
<scroll-viewscroll-y="true"class="date_box">
<view
v-for="dateineffectRecentDate"
:key="date.date_zh"
:class="[date_item,selectedDate.date_zh==date.date_zh?date_active:`]&quot; @click=&quot;timeChange(date,&#39;date&#39;)&quot; &gt; {{date.date_zh}}({{date.week}}) &lt;/view&gt; &lt;/scroll-view&gt; &lt;!--时间--&gt; &lt;scroll-viewscroll-y=&quot;true&quot;class=&quot;time_box&quot;&gt; &lt;view v-for=&quot;(time,index)ineffectAppointmentTime&quot; :key=&quot;index&quot; :class=&quot;{ bottom:true, time_item:true, time_active:selectedTime===time }&quot; @click=&quot;timeChange(effectAppointmentTime[index],time`)"
>
{{time}}
</view>
</scroll-view>
</view>
</view>
</uni-popup>
</template>
<script>
import{formatDate,toFixed,formatMinute}from'@/public/utils/utils';
exportdefault{
name:'TimePicker',
props:{
visible:{
required:true,
default:false
}
},
watch:{
visible(newVal){
if(newVal){
if(!this.selectedDate.date_zh){
this.selectedDate=this.effectRecentDate[0];
}
this.$refs.datePickerPop.open();
}else{
this.$refs.datePickerPop.close();
}
}
},
data(){
//生成取件日期
constrecentDayNum=5;
this.toFixed=toFixed;
return{
currentDate:formatDate(newDate(),'/'),
selectedTime:'',
selectedDate:{},
recentDateList:this.setRecentData(recentDayNum),
appointment:[
'08:00-09:00',
'09:00-10:00',
'10:00-11:00',
'11:00-12:00',
'12:00-13:00',
'13:00-14:00',
'14:00-15:00',
'15:00-16:00',
'16:00-17:00',
'17:00-18:00',
'18:00-19:00',
'19:00-20:00'
]
};
},
computed:{
//有效日期
effectRecentDate(){
consteffectAppointmentTime=this.effectAppointmentTime;
//当日取件时间全部失效
if(effectAppointmentTime.length==0){
this.recentDateList.splice(0,1);
this.selectedDate=this.recentDateList[0];
console.log('this.selectedDate:',this.selectedDate);
returnthis.recentDateList;
}else{
returnthis.recentDateList;
}
},
//有效取件时间
effectAppointmentTime(){
constappointment=this.appointment;
//未来日期返回全部
if(this.selectedDate.date_en!=this.currentDate){
returnappointment;
}
letlist=appointment.filter((item)=>this.checkRemainingMinute(item)!=1);
//当日只返回有效时间
if(list.length>0){
list.unshift('立即上门');
}
returnlist;
}
},
methods:{
handleClose(){
this.$emit('update:visible',false);
},
//生成时间选择器最近n天的时间
setRecentData(n){
constoneDayTime=60
10006024;
consttoday=+newDate();
letlist=[];
for(leti=0;i<n;i++){
letformatTime=this.formatTime_zh(today+oneDayTime*i);
list.push({
...formatTime,
week:i==0?'今天':i==1?'明天':formatTime.week
});
}
this.selectedDate=list[0];
returnlist;
},
//时间处理函数
formatTime_zh:(date)=>{
date=newDate(date);
constyear=date.getFullYear();
constmonth=date.getMonth()+1;
constday=date.getDate();
constweekDay=date.getDay();
constformatNumber=(n)=>{
n=n.toString();
returnn[1]?n:'0'+n;
};
constnumToTxt=['周日','周一','周二','周三','周四','周五','周六'];
return{
date_zh:${formatNumber(month)}月${formatNumber(day)}日,
date_en:${year}/${formatNumber(month)}/${formatNumber(day)},
week:numToTxt[weekDay]
};
},
//时间选择器修改函数
timeChange(date,type){
constdateList=this.recentDateList;
if(type==='date'){
//选择日期
this.selectedDate=date;
this.selectedTime='';
}else{
//选择时间
this.selectedTime=date;
if(this.selectedDate.date_zh==''){
this.selectedDate=dateList[0];
}
this.handleClose();
this.$emit('selectTime',this.selectedDate,this.selectedTime);
}
},
/

@return{Number}1:已过期,2:即将过期,3:未过期
/
checkRemainingMinute(time){
console.log('time:',time);
if(!time)return;
constoutTime=time.toString().split('-')[1];
constfullYearDate=formatMinute(newDate(),'/');
constnow=newDate(fullYearDate);
constdateTime=this.currentDate+''+outTime;
constcheck=newDate(dateTime);
constdifference=check-now;
constminutes=difference/(1000*60);
//minutes<=0:已过期-->1
//minutes<=90:即将过期-->2
//minutes>0:未过期-->3
returnminutes<=0?1:minutes<=90?2:3;
}
}
};
</script>
<stylescopedlang="scss">
.date_pop{
padding:0;
height:750rpx;
.popup_header{
display:flex;
align-items:center;
justify-content:space-between;
box-sizing:border-box;
padding:60rpx40rpx;
.pop_title{
font-weight:bold;
font-size:32rpx;
width:90%;
}
.pop-close{
width:60rpx;
height:60rpx;
background:url('~@/static/images/close.png');
background-size:22rpx;
background-position:center;
background-repeat:no-repeat;
}
}
.date_con{
font-size:28rpx;
position:relative;
height:600rpx;
}
.date_box{
position:absolute;
top:0;
left:0;
width:40%;
height:100%;
background:#f7f7f9;
overflow-y:scroll;
.date_item{
padding:040rpx;
line-height:100rpx;
}
.date_active{
background:#fff;
}
}
.time_box{
position:absolute;
top:0;
right:0;
width:60%;
height:100%;
.disabled{
color:#ccc;
&::after{
content:'已过期';
margin-left:130rpx;
}
}
.outTime{
color:#ccc;
&::after{
content:'即将过期';
margin-left:100rpx;
}
}
.time_item{
padding:040rpx;
line-height:100rpx;
}
}
.time_active{
color:#ff5b29;
position:relative;
&::after{
position:absolute;
content:'✔';
right:15%;
margin:auto;
}
}
}
</style>

TODO:

  • 时间区域打开显示对应选中时间位置

  • 右侧时间列表改后台返回

本文:怎么用uni-popup实现菜鸟上门取件时间选择器的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:Android数据存储方式是什么下一篇:

2 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18