效果图(未展开的样子):
效果图(展开的样子):
子组件代码:
<!--
* @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>