本文使用的技术栈是uniapp的vue版本 直接上干货,所有的核心代码讲解已在注释中添加,自取
HTML结构
<template>
<u-popup :show="show" :round="10" mode="bottom" @close="close" @open="open">
<view class="content">
<view class="title" hover-class="none" hover-stop-propagation="false">
<view
class="title-text"
hover-class="none"
hover-stop-propagation="false"
>
选择取件时间
</view>
<view class="desc" hover-class="none" hover-stop-propagation="false">
准时上门
</view>
<view class="closeIcon" @click="close">
<u-icon name="close" size="16" bold color="#000"></u-icon>
</view>
</view>
<view class="bottomView">
<scroll-view scroll-y class="left">
<view
class="left-item"
:class="[leftItemActive == item.val ? 'left-item-active' : '']"
v-for="item in leftList"
:key="item.val"
@click="leftIteClick(item)"
>
{{ item.label }}
</view>
</scroll-view>
<scroll-view scroll-y class="right">
<view
class="right-item"
v-for="item in timeList"
:key="item"
@click="rightItemClick(item)"
>
<view
class="item-text"
:class="[
rightTimeActive == item
? 'right-item-active'
: judgeText(item)
? 'left-item-disable'
: '',
]"
>{{ item }}</view
>
<view class="item-state"
><u-icon
v-if="!judgeText(item) && rightTimeActive == item"
name="checkmark-circle"
color="#15be77"
size="20"
style="margin-top: 2px"
></u-icon>
<text
v-if="judgeText(item)"
style="color: #c0c0c0; font-size: 0.7rem"
>
已过期
</text></view
>
</view>
</scroll-view>
</view>
</view>
</u-popup>
</template>
方法
import { ref, watch } from "vue";
import moment from "moment";
import { onShow } from "@dcloudio/uni-app";
const show = ref(false);
const leftList = ref([
// 左侧选择的时间列表数据集合。
{
label: "今天",
val: 1,
},
{
label: "明天",
val: 2,
},
{
label: "后天",
val: 3,
},
]);
const leftItemActive = ref(); //左侧时间选中列表标志
const leftTime = ref(); //与右侧时间进行交互
const timeList = ref([
//右侧时间列表
"09:00 ~ 11:00",
"11:00 ~ 13:00",
"13:00 ~ 17:00",
"17:00 ~ 19:00",
]);
const rightTimeActive = ref(); //右侧选中标志
const emit = defineEmits<{
(e: "timeClick", value: any);
}>();
watch(leftItemActive, (newVal, oldVal) => {
//切换左侧时间时,清空右侧选择状态
rightTimeActive.value = "";
});
const close = () => {
show.value = false;
};
const open = () => {
show.value = true;
};
const leftIteClick = (item) => {
//给左侧添加选中样式以及储存选中的变量,与右侧交互时使用
leftItemActive.value = item.val;
switch (item.val) {
case 0:
leftTime.value = moment(new Date())
.subtract(1, "days")
.format("YYYY-MM-DD");
break;
case 1:
leftTime.value = moment(new Date()).format("YYYY-MM-DD");
break;
case 2:
leftTime.value = moment(new Date()).add(1, "days").format("YYYY-MM-DD");
break;
}
};
const judgeText = (item) => {
//判断时间是否超时
let arr = item.split("~");
//获取预约时间段最早的时刻
let time = leftTime.value + " " + arr[0];
与现在的时间比较
if (moment(time).diff(moment(new Date()), "minutes") < 0) {
return true;
} else {
return false;
}
};
const rightItemClick = (item) => {
if (judgeText(item)) {
//终止已过期时间的后续操作
return;
}
//添加右侧选中事件样式
rightTimeActive.value = item;
//抛出的数据
let returnData = leftList.value[Number(leftItemActive.value)-1].label + " " + item;
emit("timeClick", returnData);
close()
};
onShow(() => {
//获取每天最晚的预约时间
let curTime = moment(new Date()).format("YYYY-MM-DD") + " " + "17:00";
console.log(moment(new Date()).diff(moment(curTime), "minutes"));
//进入页面自动选中左侧的时间
if (moment(new Date()).diff(moment(curTime), "minutes") > 0) {
leftIteClick(leftList.value[1]);
} else {
leftIteClick(leftList.value[0]);
}
});
defineExpose({ open });
样式
.title {
display: flex;
flex-direction: column;
align-items: flex-start;
width: calc(100% - 3rem);
position: relative;
padding: 1.5rem;
.title-text {
color: black;
font-size: 1.4rem;
font-weight: 800;
margin-bottom: 0.5rem;
}
.desc {
color: $sch-theme-color;
font-size: 0.8rem;
}
.closeIcon {
position: absolute;
top: 2rem;
right: 1.5rem;
}
}
.bottomView {
display: flex;
height: calc(100% - 5.7rem);
.left {
width: 30%;
height: 100%;
display: flex;
flex-direction: column;
.left-item {
width: 100%;
height: 3rem;
background-color: #cec6c62e;
color: black;
text-align: center;
line-height: 3rem;
font-size: 1rem;
}
}
.right {
flex: 1;
.right-item {
width: calc(100% - 2rem);
height: 3rem;
padding: 0 1rem;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #acaaaa2e;
}
}
}
// 点击样式
.left-item-active {
background-color: #fff !important;
color: $sch-theme-color !important;
}
.left-item-disable {
color: $uni-text-color-disable;
}
.right-item-active {
color: $sch-theme-color;
}