uniapp+ts模拟popup弹出框(下拉框)
效果图(未展开的样子):
效果图(展开的样子):
子组件代码:
<!--* @Date: 2024-04-26 14:30:00* @LastEditTime: 2025-05-29 09:01:06* @Description: 技术服务
-->
<template><view class="reg-info"><view class="item-class"><view class="title-region flex-center-start" @click="arrowClick()"><view class="title">{{ currentDate }}</view><view class="arrow-region"><view class="iconfont icon-arrow-chevron-down1" /></view></view><view class="content-region" :style="{ height: showSelect ? `${dateContBgHeight}vh` : '0' }"><view class="content-region-cont" :style="{ height: showSelect ? `${dateContHeight}rpx` : '0' }"><view class="content-item-box"><viewv-for="(item, index) in dateList":key="index"class="content-item flex-column-center":class="{ selected: item.date === currentDate }"@click="selectDate(item)"><view class="server-order-week">{{ item.week }}</view><view class="server-order-date">{{ item.date }}</view><view class="server-order-num"> (12) </view></view></view></view></view></view></view>
</template><script setup lang="ts">
import { ref } from 'vue';
import { formatDateAsMD } from '@/utils/DateUtils';
// 星期映射表
const WEEKDAYS = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];const currentDate = ref(formatDateAsMD(new Date())); // 默认今日日期
const showSelect = ref(true); //下拉框
const dateContBgHeight = ref(100); //遮罩层
const dateContHeight = ref(584); //484白色弹框
// 获取当前日期对象
const today = new Date();
// 用于存储日期的数组 - 修改为对象数组格式
const dateList = ref<{ week: string; date: string }[]>([]);// 填充前4天的日期
for (let i = 4; i > 0; i--) {const tempDate = new Date(today.getTime() - i * 24 * 60 * 60 * 1000);const month = (tempDate.getMonth() + 1).toString().padStart(2, '0');const day = tempDate.getDate().toString().padStart(2, '0');const week = WEEKDAYS[tempDate.getDay()]; // 获取星期几dateList.value.push({week,date: `${month}.${day}`,});
}// 填充今天的日期
const todayMonth = (today.getMonth() + 1).toString().padStart(2, '0');
const todayDay = today.getDate().toString().padStart(2, '0');
const todayWeek = WEEKDAYS[today.getDay()]; // 获取今天星期几
dateList.value.push({week: todayWeek,date: `${todayMonth}.${todayDay}`,
});// 填充后11天的日期
for (let i = 1; i <= 11; i++) {const tempDate = new Date(today.getTime() + i * 24 * 60 * 60 * 1000);const month = (tempDate.getMonth() + 1).toString().padStart(2, '0');const day = tempDate.getDate().toString().padStart(2, '0');const week = WEEKDAYS[tempDate.getDay()]; // 获取星期几dateList.value.push({week,date: `${month}.${day}`,});
}const arrowClick = () => {showSelect.value = !showSelect.value;
};// 新增日期选择方法
const selectDate = (item: { week: string; date: string }) => {currentDate.value = item.date;showSelect.value = false;
};
</script>
<style lang="scss">
// @import './index.scss';
.reg-info {height: auto;background: #fff;padding: 40rpx 0 0 0;.item-class {&:nth-child(n + 2) {margin: 40rpx 0 0 0;}.title-region {padding: 0 30rpx;position: absolute;//父组件最外层div设置position: relative;height: 45rpx;font-family: DINAlternate, DINAlternate;font-weight: bold;font-size: 28rpx;color: #13161b;line-height: 32rpx;}.content-region {width: 100%;background: rgba(0, 0, 0, 0.5);margin: 20rpx 0 0 0;overflow: hidden;position: absolute;left: 0;top: 61rpx;height: 0rpx;.content-region-cont {height: 0rpx;padding: 20rpx 40rpx;background: #ffffff;transition: all 0.38s;}.content-item-box {display: grid;grid-template-columns: repeat(4, 1fr);border-left: 1px solid rgba(151, 151, 151, 0.2);border-top: 1px solid rgba(151, 151, 151, 0.2);}.content-item {border-right: 1px solid rgba(151, 151, 151, 0.2);border-bottom: 1px solid rgba(151, 151, 151, 0.2);padding: 4rpx 0;}.selected {background-color: rgba(255, 233, 179, 0.2);color: rgba(255, 167, 38, 1);}}}
}
</style>
父组件代码
<template><view class="service-order"> <view class="service-order-filter flex"><timeSelect /></view></view>
</template><script setup lang="ts">import timeSelect from '@/components/time-select/time-select.vue';//引入子组件
</script><style lang="scss">
.service-order {width: 100vw;background: #f1f2f5;box-sizing: border-box;position: relative;//父组件一定要定义.service-order-filter{width: 100%;background: #fff;position: sticky;height: 80rpx;top: 0;left: 0;}
</style>