upload project source code
This commit is contained in:
115
前端源码/uni-app/components/CustomTabBar.vue
Normal file
115
前端源码/uni-app/components/CustomTabBar.vue
Normal file
@@ -0,0 +1,115 @@
|
||||
<template>
|
||||
<view class="tabbar">
|
||||
<view class="tabbar-inner">
|
||||
<view v-for="tab in tabs" :key="tab.id" class="tab-btn" :class="{ active: currentTab === tab.id }"
|
||||
@click="$emit('change', tab.id)">
|
||||
<view class="tab-icon">
|
||||
<HomeIcon v-if="tab.id === 'home'" size="24" class="tab-icon-svg" />
|
||||
<TestIcon v-else-if="tab.id === 'test'" size="24" class="tab-icon-svg" />
|
||||
<NamingIcon v-else-if="tab.id === 'naming'" size="24" class="tab-icon-svg" />
|
||||
<RenamingIcon v-else-if="tab.id === 'renaming'" size="24" class="tab-icon-svg" />
|
||||
<ProfileIcon v-else-if="tab.id === 'profile'" size="24" class="tab-icon-svg" />
|
||||
<text v-else class="icon-dot" />
|
||||
</view>
|
||||
<text class="tab-label">{{ tab.label }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import HomeIcon from "./icons/HomeIcon.vue";
|
||||
import TestIcon from "./icons/TestIcon.vue";
|
||||
import NamingIcon from "./icons/NamingIcon.vue";
|
||||
import RenamingIcon from "./icons/RenamingIcon.vue";
|
||||
import ProfileIcon from "./icons/ProfileIcon.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
currentTab: string;
|
||||
}>();
|
||||
|
||||
const tabs = [
|
||||
{ id: "home", label: "首页" },
|
||||
{ id: "test", label: "测名" },
|
||||
{ id: "naming", label: "起名" },
|
||||
{ id: "renaming", label: "改名" },
|
||||
{ id: "profile", label: "我的" }
|
||||
];
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.tabbar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: #fdfbf7;
|
||||
border-top: 2px solid #dcd3c9;
|
||||
box-shadow: 0 -4px 6px -1px rgba(0, 0, 0, 0.05);
|
||||
z-index: 999;
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
.tabbar-inner {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
height: 60px;
|
||||
padding: 10px 0;
|
||||
max-width: 750px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.tab-btn {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
color: #5a5a5a;
|
||||
font-size: 12px;
|
||||
letter-spacing: 0.2em;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.tab-btn:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.tab-btn.active {
|
||||
color: #8b2323;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.tab-icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(139, 35, 35, 0.05);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.tab-btn:not(.active) .tab-icon {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.tab-icon-svg {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.icon-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: currentColor;
|
||||
opacity: 0.9;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user