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">
                        <view
                            v-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);//固定显示4个
        }
        .content-item {
            border: 2rpx solid rgba(151, 151, 151, 0.2);
            margin-left: -2rpx; /* 抵消相邻边框 */
            margin-top: -2rpx; /* 抵消相邻边框 */
            padding: 4rpx 0;
            height: 110rpx;
            box-sizing: border-box;
            position: relative;
            z-index: 1;
        }
      /* 处理边缘边框 */
        .content-item:nth-child(4n + 1) {
            margin-left: 0;
        }
        .content-item:nth-child(-n + 4) {
            margin-top: 0;
        }
            .selected {
                color: rgba(255, 167, 38, 1);
            border-color: rgba(255, 167, 38, 1);
            background: rgba(255, 233, 179, 0.20);
            z-index: 2;
            }
        }
    }
}
</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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值