uni-app 官方 tabbar 不支持凸起按钮,必须禁用原生 tabbar 并用自定义组件(如 uni-tab-bar)配合 fixed 定位实现;中间按钮需单独抽离、设 z-index 和 pointer-events:auto,非 tabbar 页面须手动引入同一 tabbar 并同步状态栏与 tab 高亮。

uni-app 中 bottom-tabbar 凸起发布按钮的实现原理
直接说结论:uni-app 官方 tabBar 配置不支持凸起按钮,所谓“闲鱼式”底部导航必须放弃原生 tabBar,改用自定义 uni-tabbar 或纯 view 模拟。否则无论怎么 hack(比如在 tabBar 上叠层按钮),都会遇到 iOS 微信 WebView 下点击穿透、iOS 系统手势冲突、安卓状态栏遮挡等真机问题。
用自定义 tabbar 组件 + fixed 定位实现凸起按钮
推荐使用 uni-app 社区较稳定的 uni-tabbar(如 @dcloudio/uni-ui 中的 uni-tab-bar),它允许你完全控制每个 tab 的渲染结构。关键点是把中间按钮单独抽离,用 position: fixed + bottom + z-index 突出:
- 在页面根容器外额外加一个
<view class="fab-btn"></view>,class 内设bottom: 30rpx(避开 tabBar 高度)、left: 50%、transform: translateX(-50%) - tabBar 的 5 个 tab 里,中间项留空或用透明占位,避免点击区域重叠
- 务必给凸起按钮设置
pointer-events: auto(某些版本 H5 下默认为 none) - 在
pages.json中关闭原生 tabBar:"tabBar": {"list": []},否则自定义 tabbar 会被压在底下
凸起按钮点击后跳转页面但保持 tabbar 显示的处理
闲鱼的发布按钮点击后进的是新页面,但底部 tabbar 依然存在——这说明目标页不能是 tabBar 页面(即不能写在 tabBar.list 里),而应通过 uni.navigateTo 打开普通页面,并在该页面中手动引入相同的自定义 tabbar 组件:
- 所有非 tabBar 页面(包括发布页)都需在
<template></template>底部插入同一份<custom-tabbar></custom-tabbar> - 发布页的
onLoad中调用uni.setNavigationBarColor同步状态栏颜色,避免和上一页不一致 - 如果发布页需要返回时高亮“首页”tab,可在
onShow中触发父组件的 tab 切换事件(通过uni.$emit或 vuex)
真机适配常见坑:iOS 微信、iOS App、安卓全面屏
凸起按钮在不同环境偏移量差异极大,别依赖固定 rpx 值:
- iOS 微信 WebView 下,
env = uni.getSystemInfoSync().platform === 'ios'且uni.getSystemInfoSync().webViewVersion存在时,建议用bottom: calc(20px + env(safe-area-inset-bottom))(H5)或动态注入 CSS 变量 - App 端需在
manifest.json → iOS 设置 → “启动图”勾选“使用安全区域”,否则凸起按钮会沉入 home indicator 区域 - 安卓全面屏下,部分厂商(如华为)会把虚拟导航栏高度算进
screenHeight,但不反映在safeAreaInsets,此时要用uni.getSystemInfo的screenHeight - windowBottom反推可安全区域 - 凸起按钮图标建议用
font-icon或base64图片,避免网络图加载空白期导致按钮“闪一下”
凸起按钮不是加个 position: fixed 就完事,它的定位基准、层级关系、安全区兼容、跨平台行为差异,每一块都得单独校验。尤其当项目已上线,临时加这个效果,最容易翻车的是 iOS 微信里按钮点不动,或者安卓全面屏下按钮被导航栏盖住一半——这些都得在真机上逐个测,模拟器看不出问题。











