144 lines
3.0 KiB
Vue
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>
|