描述
uniapp vue3 自定义底部导航栏,自动占位,不需要在使用的页面使用margin-bottom或padding-bottom占位。
效果
tabbar.vue 组件代码
<template>
<view class="tabbar-area">
<view class="tabbar-fill" :style="{ height: tabbarHeight }"></view>
<view class="tabbar-bottom" :style="{ backgroundColor: backgroundColor, height: tabbarHeight }">
<view class="tabbar-bottom-item" v-for="(item, index) in tabbars" :key="index" @click="switchTab(item)">
<view class="tabbar-bottom-item-bg">
<image :src="currentIndex == index + 1 ? item.selectedIconPath : item.iconPath" class="tabbar-bottom-item-icon"></image>
<view
class="tabbar-bottom-item-text"
:style="{
color: currentIndex == index + 1 ? textActiveColor : textColor
}"
>
{{ item.text }}
</view>
<view class="tabbar-bottom-item-count" v-if="item.count">{{ item.count > 99 ? '99+' : item.count }}</view>
</view>
</view>
</view>
</view>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const props = defineProps({
currentIndex: {
type: Number,
default: 0
},
backgroundColor: {
type: String,
default: '#fff'
},
textColor: {
type: String,
default: '#717171'
},
textActiveColor: {
type: String,
default: '#1ABC9C'
},
tabbarHeight: {
type: String,
default: '120rpx'
}
});
const tabbars = ref([
{
key: 1,
text: '首页',
pagePath: '/pages/comment/index',
iconPath: '/static/tabbar_comment_unpre.png',
selectedIconPath: '/static/tabbar_comment_pre.png'
},
{
key: 2,
text: '消息',
count: 0,
pagePath: '/pages/index/index',
iconPath: '/static/tabbar_message_unpre.png',
selectedIconPath: '/static/tabbar_message_pre.png'
},
{
key: 3,
text: '我的',
pagePath: '/pages/profile/index',
iconPath: '/static/tabbar_profile_unpre.png',
selectedIconPath: '/static/tabbar_profile_pre.png'
}
]);
const switchTab = item => {
uni.switchTab({
url: item.pagePath
});
};
uni.hideTabBar();
</script>
<style lang="scss" scoped>
.tabbar-area {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
.tabbar-fill {
height: 120rpx;
}
.tabbar-bottom {
height: 120rpx;
width: 100%;
display: flex;
box-shadow: 0rpx 4rpx 22rpx 0rpx rgba(0, 0, 0, 0.1);
z-index: 998;
box-sizing: border-box;
position: fixed;
bottom: 0;
left: 0;
.tabbar-bottom-item {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
flex: 1;
.tabbar-bottom-item-bg {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: relative;
.tabbar-bottom-item-icon {
height: 48rpx;
width: 48rpx;
position: relative;
display: block;
}
.tabbar-bottom-item-text {
display: flex;
font-size: 20rpx;
align-items: center;
justify-content: center;
margin: 6rpx 0 0 0;
color: rgb(113, 113, 113);
}
.tabbar-bottom-item-count {
height: 28rpx;
display: flex;
background: #ff4d4d;
border-radius: 1000rpx;
font-size: 20rpx;
font-weight: bold;
color: #ffffff;
align-items: center;
justify-content: center;
padding: 0 4rpx;
min-width: 20rpx;
position: absolute;
top: -8rpx;
left: 32rpx;
}
}
}
}
}
</style>
在页面使用
<template>
<Tabbar :currentIndex="1" />
</template>
<script lang="ts" setup>
import Tabbar from '@/components/BasisLayout/Tabbar.vue';
</script>
在APP.vue
onLaunch: function() {
uni.hideTabBar();
}