Files
assistant/components/BottomTabBar.uvue

94 lines
1.8 KiB
Plaintext

<template>
<view class="tabbar">
<view
v-for="tab in tabs"
:key="tab.key"
class="tabbar__item"
@tap="onTap(tab.key)"
>
<text class="tabbar__icon">{{ tab.icon }}</text>
<text
class="tabbar__label"
:class="{ 'tabbar__label--active': activeKey === tab.key }"
>{{ tab.label }}</text>
<view v-if="activeKey === tab.key" class="tabbar__indicator"></view>
</view>
</view>
</template>
<script setup lang="uts">
import type { TabKey } from '@/types/index'
const props = defineProps<{
activeKey: TabKey
}>()
const emit = defineEmits<{
change: [key: TabKey]
}>()
const tabs = [
{ key: 'workspace' as TabKey, icon: '📂', label: '工作空间' },
{ key: 'chat' as TabKey, icon: '💬', label: '对话' },
{ key: 'profile' as TabKey, icon: '👤', label: '我的' },
]
function onTap(key: TabKey): void {
if (key !== props.activeKey) {
emit('change', key)
}
}
</script>
<style scoped>
.tabbar {
display: flex;
flex-direction: row;
align-items: center;
background: rgba(15, 15, 26, 0.92);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border-top: 1px solid rgba(255, 255, 255, 0.06);
padding-bottom: env(safe-area-inset-bottom);
}
.tabbar__item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
padding: 14rpx 0 10rpx;
position: relative;
transition: opacity 0.2s ease;
}
.tabbar__item:active {
opacity: 0.7;
}
.tabbar__icon {
font-size: 40rpx;
margin-bottom: 4rpx;
}
.tabbar__label {
font-size: 20rpx;
color: rgba(255, 255, 255, 0.4);
transition: color 0.2s ease;
}
.tabbar__label--active {
color: #a29bfe;
font-weight: 600;
}
.tabbar__indicator {
position: absolute;
top: 0;
width: 40rpx;
height: 4rpx;
border-radius: 2rpx;
background: linear-gradient(90deg, #6c5ce7, #a29bfe);
}
</style>