Files
used-car-h5/components/CustomTabBar/CustomTabBar.vue
T
2026-01-19 14:47:43 +08:00

144 lines
3.0 KiB
Vue

<template>
<view class="custom-tabbar" :style="{ paddingBottom: safeAreaInsets.bottom + 'px' }">
<view
v-for="(item, index) in tabList"
:key="index"
class="tab-item"
:class="{ active: current === index }"
@tap="switchTab(item, index)"
>
<image
class="tab-icon"
:src="current === index ? item.selectedIconPath : item.iconPath"
mode="aspectFit"
/>
<text class="tab-text">{{ item.text }}</text>
</view>
</view>
</template>
<script>
import { getVisibleTabBar, getCurrentTabIndex, getUserRole } from '@/common/tabbar.js'
export default {
name: 'CustomTabBar',
data() {
return {
current: 0,
safeAreaInsets: {
bottom: 0
}
}
},
computed: {
tabList() {
// 根据权限获取可见的 tabbar 列表
const userRole = getUserRole()
return getVisibleTabBar(userRole)
}
},
onLoad() {
this.updateCurrent()
this.initSafeArea()
},
onShow() {
// 页面显示时更新当前 tab 索引
this.updateCurrent()
},
watch: {
// 监听 tabList 变化,当角色改变导致 tabbar 列表变化时,更新当前索引
tabList: {
handler() {
this.updateCurrent()
},
immediate: true
}
},
methods: {
initSafeArea() {
// 获取安全区域信息(适配 iPhone X 等)
// #ifdef APP-PLUS || H5
try {
const systemInfo = uni.getSystemInfoSync()
this.safeAreaInsets = systemInfo.safeAreaInsets || { bottom: 0 }
} catch (e) {
this.safeAreaInsets = { bottom: 0 }
}
// #endif
},
updateCurrent() {
const pages = getCurrentPages()
if (pages.length === 0) return
const currentPage = pages[pages.length - 1]
const currentPath = currentPage.route || currentPage.$route?.path || ''
const index = getCurrentTabIndex(currentPath)
// 如果当前页面不在可见的 tabbar 列表中,保持当前索引或设为 0
this.current = index >= 0 ? index : 0
},
switchTab(item, index) {
if (this.current === index) {
return
}
uni.switchTab({
url: '/' + item.pagePath,
fail: (err) => {
// 如果 switchTab 失败,可能是该页面不在 tabBar 中,使用 navigateTo
uni.navigateTo({
url: '/' + item.pagePath,
fail: () => {
console.error('导航失败:', err)
}
})
}
})
}
}
}
</script>
<style lang="scss" scoped>
.custom-tabbar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 100rpx;
background: #fff;
border-top: 1px solid #e5e5e5;
display: flex;
align-items: center;
justify-content: space-around;
z-index: 999;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);
}
.tab-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
transition: all 0.2s;
}
.tab-item.active {
.tab-text {
color: #3F435B;
}
}
.tab-icon {
width: 44rpx;
height: 44rpx;
margin-bottom: 8rpx;
}
.tab-text {
font-size: 24rpx;
color: #7A7E83;
transition: color 0.2s;
}
</style>