场景复现
需要根据不同的业务场景显示不同的 Tabbar ,官方 Tabbar 配置无法支持,只能通过自定义 Tabbar 实现
解决方案
方案一
- 正常配置
Tabbar页面,但需要将Tabbar隐藏
"tabBar": {
"custom": true,
"list": [
{
"pagePath": "pages/home"
},
{
"pagePath": "pages/test"
}
]
}
依然在 pages.json 中正常配置 Tabbar 页面,避免跳转 Tabbar 路径时出现默认的页面切换动画效果
微信小程序可使用 custom: true 隐藏( Uniapp 官方文档 目前并没有写明这个参数,但 微信小程序 原生支持)
微信小程序自定义
Tabbardevelopers.weixin.qq.com/miniprogram…
其他端可采用 uni.hideTabBar() 或 Uniapp tabbar height 配置(小程序环境不支持)实现
- 自定义布局实现
Tabbar相关逻辑即可
方案二
完全采用自定义动态组件方式实现
实现自定义 Tabbar 状态缓存
默认 Tabbar 页面是自带状态缓存的,自定义 Tabbar 实现由于 uni 在非 h5 端不支持 keep-alive 与 <component /> ,需手动通过 v-if 与 v-show 实现(参考 antfu/v-lazy-show),通过 v-if 控制首次渲染,后续切换通过 v-show 控制,即可实现简易自定义 Tabbar 关联 页面/组件 状态缓存
示例:
<script setup>
const userTabbarMap = reactive({
home: { label: '首页', icon: 'tabbar_home', rendered: false },
teacher: { label: '教师', icon: 'tabbar_teacher', rendered: false },
found: { label: '广场', icon: 'tabbar_found', rendered: false },
mine: { label: '我的', icon: 'tabbar_mine', rendered: false },
})
/** TODO: 其他身份 tabbar 配置 */
const teacherTabbarMap = {}
const curTabbar = ref('')
watch(curTabbar, v => (userTabbarMap[v].rendered = true))
// 由具体业务逻辑控制
curTabbar.value = 'home'
</script>
<template>
<view class="h-screen flex-(~ col)">
<view class="flex-1 overflow-auto">
<!-- 通过 v-if 控制首次渲染,后续切换通过 v-show 控制 -->
<Home v-if="userTabbarMap.home.rendered" v-show="curTabbar === 'home'" />
<Teacher v-if="userTabbarMap.teacher.rendered" v-show="curTabbar === 'teacher'" />
<Found v-if="userTabbarMap.found.rendered" v-show="curTabbar === 'found'" />
<Mine v-if="userTabbarMap.mine.rendered" v-show="curTabbar === 'mine'" />
</view>
<!-- tabbar -->
<view class="h-15 bg-white flex">
<view v-for="(v, k) in userTabbarMap" :key="k" @click="curTabbar = k" class="flex-1 flex-(~ col) justify-center items-center">
<image :src="handleAssetsUrl(curTabbar === k ? `${v.icon}_active` : `${v.icon}`)" class="size-6.5" />
<text class="text-(3 #999) mt-.5" :class="{ '!text-#000': curTabbar === k }">{{ v.label }}</text>
</view>
</view>
</view>
</template>