2026-05-26 17:12:12 +08:00

90 lines
2.2 KiB
Vue

<template>
<view class="parent-tab">
<view
v-for="item in tabs"
:key="item.key"
class="tab-item"
:class="{ active: item.key === props.active }"
@click="goPage(item)"
>
<view class="tab-icon">
<text>{{ item.icon }}</text>
</view>
<text class="tab-label">{{ item.label }}</text>
</view>
</view>
</template>
<script setup lang="ts">
type TabKey = 'home' | 'reports' | 'profile';
const props = defineProps<{
active: TabKey;
}>();
const tabs: { key: TabKey; label: string; icon: string; url: string }[] = [
{ key: 'home', label: '首页', icon: '首', url: '/pages/parent/home/index' },
{ key: 'reports', label: '考试报告', icon: '报', url: '/pages/parent/reports/index' },
{ key: 'profile', label: '个人中心', icon: '我', url: '/pages/parent/profile/index' },
];
// 分包内页面模拟 tab 切换,用 redirectTo 避免重复堆叠页面栈。
const goPage = (item: (typeof tabs)[number]) => {
if (item.key === props.active) return;
uni.redirectTo({ url: item.url });
};
</script>
<style lang="scss" scoped>
.parent-tab {
position: fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 2;
height: calc(112rpx + env(safe-area-inset-bottom));
padding-bottom: env(safe-area-inset-bottom);
display: grid;
grid-template-columns: repeat(3, 1fr);
background: rgba(255, 255, 255, 0.94);
border-top: 2rpx solid rgba(14, 116, 144, 0.08);
box-shadow: 0 -12rpx 36rpx rgba(15, 118, 110, 0.08);
}
.tab-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 6rpx;
color: #64748b;
}
.tab-icon {
width: 44rpx;
height: 44rpx;
border-radius: 16rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 22rpx;
font-weight: 900;
background: #f8fafc;
}
.tab-label {
font-size: 22rpx;
font-weight: 600;
}
.tab-item.active {
color: #0891b2;
.tab-icon {
color: #ffffff;
background: linear-gradient(180deg, #22d3ee 0%, #0891b2 100%);
box-shadow: 0 8rpx 18rpx rgba(8, 145, 178, 0.28);
}
}
</style>