Files
Evergreen-Health-Mobile/src/components/AppTabBar.vue
T
2026-10-09 16:46:35 +08:00

162 lines
4.7 KiB
Vue

<script setup lang="ts">
import { computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
const route = useRoute()
const router = useRouter()
const currentTab = computed(() => {
const path = route.path
if (path.startsWith('/assessment')) return 'assessment'
if (path.startsWith('/tcm-assessment')) return 'tcm'
if (path.startsWith('/profile')) return 'profile'
return 'home'
})
function navigate(target: string) {
if (target === 'home' && route.path !== '/dashboard') {
router.replace('/dashboard')
} else if (target === 'assessment' && route.path !== '/assessment') {
router.replace('/assessment')
} else if (target === 'tcm' && route.path !== '/tcm-assessment') {
router.replace('/tcm-assessment')
} else if (target === 'profile' && route.path !== '/profile') {
router.replace('/profile')
}
}
</script>
<template>
<nav class="app-tab-bar" aria-label="主导航">
<button type="button"
class="tab-item"
:class="{ active: currentTab === 'home' }"
:aria-current="currentTab === 'home' ? 'page' : undefined"
@click="navigate('home')"
>
<div class="tab-icon">
<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" />
<polyline points="9 22 9 12 15 12 15 22" />
</svg>
</div>
<span class="tab-label">首页</span>
</button>
<button type="button"
class="tab-item"
:class="{ active: currentTab === 'tcm' }"
:aria-current="currentTab === 'tcm' ? 'page' : undefined"
@click="navigate('tcm')"
>
<div class="tab-icon">
<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="9" />
<path d="M12 3c-4 4-4 8 0 9s4 5 0 9" />
<circle cx="9" cy="8" r="1" fill="currentColor" stroke="none" />
<circle cx="15" cy="16" r="1" fill="currentColor" stroke="none" />
</svg>
</div>
<span class="tab-label">中医四诊</span>
</button>
<button type="button"
class="tab-item"
:class="{ active: currentTab === 'assessment' }"
:aria-current="currentTab === 'assessment' ? 'page' : undefined"
@click="navigate('assessment')"
>
<div class="tab-icon">
<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
<polyline points="14 2 14 8 20 8" />
<path d="M9 13h6" />
<path d="M9 17h6" />
<polyline points="10 9 12 11 14 9" />
</svg>
</div>
<span class="tab-label">健康评估</span>
</button>
<button type="button"
class="tab-item"
:class="{ active: currentTab === 'profile' }"
:aria-current="currentTab === 'profile' ? 'page' : undefined"
@click="navigate('profile')"
>
<div class="tab-icon">
<svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" />
<circle cx="12" cy="7" r="4" />
</svg>
</div>
<span class="tab-label">我的</span>
</button>
</nav>
</template>
<style scoped>
.app-tab-bar {
position: fixed;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 100%;
max-width: 480px;
min-height: 56px;
height: calc(56px + env(safe-area-inset-bottom, 0px));
box-sizing: border-box;
background: rgba(255, 255, 255, 0.98);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border-top: 1px solid rgba(18, 63, 55, 0.08);
display: flex;
justify-content: space-around;
align-items: flex-start;
padding-top: 6px;
padding-bottom: env(safe-area-inset-bottom, 0px);
z-index: 999;
box-shadow: 0 -4px 16px rgba(18, 63, 55, 0.04);
}
.tab-item {
border: 0;
background: transparent;
font: inherit;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
flex: 1;
height: 44px;
color: #7d8e87;
cursor: pointer;
transition: color 0.2s ease;
user-select: none;
}
.tab-icon {
width: 22px;
height: 22px;
display: flex;
align-items: center;
justify-content: center;
}
.tab-label {
font-size: 11px;
font-weight: 500;
letter-spacing: 0.02em;
margin-top: 2px;
line-height: 1.2;
}
.tab-item.active {
color: #0c5045;
}
.tab-item.active .tab-label {
font-weight: 700;
}
</style>