| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- <template>
- <view class="custom-tabbar" :style="{ paddingBottom: safeAreaBottom + 'px' }">
- <view
- class="tabbar-item"
- v-for="(item, index) in tabList"
- :key="index"
- @click="handleTabClick(item, index)"
- >
- <view class="icon-wrapper">
- <!-- 首页特殊处理:滚动后显示向上箭头 -->
- <template v-if="index === 0 && showBackTop && currentIndex === 0">
- <view class="back-top-icon">
- <uni-icons type="arrow-up" size="24" color="#F8C008"></uni-icons>
- </view>
- </template>
- <template v-else>
- <image
- :src="currentIndex === index ? item.selectedIconPath : item.iconPath"
- mode="aspectFit"
- class="icon-img"
- />
- </template>
- </view>
- <text :class="['tabbar-text', { active: currentIndex === index || (index === 0 && showBackTop && currentIndex === 0) }]">
- {{ index === 0 && showBackTop && currentIndex === 0 ? '顶部' : item.text }}
- </text>
- </view>
- </view>
- </template>
- <script setup>
- import { ref, computed, onMounted } from 'vue';
- const props = defineProps({
- // 当前选中的 tab 索引
- current: {
- type: Number,
- default: 0
- },
- // 是否显示回到顶部(由首页传入)
- showBackTop: {
- type: Boolean,
- default: false
- }
- });
- const emit = defineEmits(['tabChange', 'backTop']);
- // tabBar 配置
- const tabList = ref([
- {
- pagePath: '/pages/index/index',
- iconPath: '/static/images/tabbar/1-001.png',
- selectedIconPath: '/static/images/tabbar/1-003.png',
- text: '首页'
- },
- {
- pagePath: '/pages/goods_cate/goods_cate',
- iconPath: '/static/images/2-001.png',
- selectedIconPath: '/static/images/2-003.png',
- text: '分类'
- },
- {
- pagePath: '/pages/order_addcart/order_addcart',
- iconPath: '/static/images/tabbar/3-001.png',
- selectedIconPath: '/static/images/tabbar/3-003.png',
- text: '购物车'
- },
- {
- pagePath: '/pages/user/index',
- iconPath: '/static/images/tabbar/4-001.png',
- selectedIconPath: '/static/images/tabbar/4-003.png',
- text: '我的'
- }
- ]);
- const currentIndex = computed(() => props.current);
- // 安全区域底部高度
- const safeAreaBottom = ref(0);
- onMounted(() => {
- const systemInfo = uni.getSystemInfoSync();
- safeAreaBottom.value = systemInfo.safeAreaInsets?.bottom || 0;
- });
- // 处理 tab 点击
- const handleTabClick = (item, index) => {
- // 如果是首页且显示回到顶部状态,触发回到顶部
- if (index === 0 && props.showBackTop && currentIndex.value === 0) {
- emit('backTop');
- return;
- }
-
- // 如果点击的是当前页,不做处理
- if (index === currentIndex.value) {
- return;
- }
-
- // 切换 tab
- emit('tabChange', index);
- uni.switchTab({
- url: item.pagePath
- });
- };
- </script>
- <style lang="scss" scoped>
- .custom-tabbar {
- position: fixed;
- bottom: 0;
- left: 0;
- right: 0;
- display: flex;
- justify-content: space-around;
- align-items: center;
- height: 160rpx;
- background-color: #ffffff;
- border-top: 1rpx solid #e5e5e5;
- z-index: 9999;
-
- .tabbar-item {
- flex: 1;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- padding: 10rpx 0;
-
- .icon-wrapper {
- width: 50rpx;
- height: 50rpx;
- display: flex;
- align-items: center;
- justify-content: center;
-
- .icon-img {
- width: 50rpx;
- height: 50rpx;
- }
-
- .back-top-icon {
- width: 50rpx;
- height: 50rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- animation: bounce 0.5s ease-in-out;
-
- .icon-img {
- width: 50rpx;
- height: 50rpx;
- }
- }
- }
-
- .tabbar-text {
- font-size: 22rpx;
- color: #999999;
- margin-top: 6rpx;
-
- &.active {
- color: #F8C008;
- }
- }
- }
- }
- @keyframes bounce {
- 0%, 100% {
- transform: translateY(0);
- }
- 50% {
- transform: translateY(-5rpx);
- }
- }
- </style>
|