titlenview.buttons 仅在 app-plus 端生效,因依赖原生 webviewtitlenviewstyles;h5 和小程序不支持该配置,需自定义导航栏实现统一效果。

只能在 app-plus 端用 titleNView.buttons 配置实现,H5 和小程序完全不生效——这不是 bug,是 uni-app 的原生渲染机制决定的。
为什么只在 app-plus 有效
titleNView 是基于 plus.webview.WebviewTitleNViewStyles 的原生导航栏能力,仅 Android/iOS 原生容器支持。H5 渲染在 WebView 内部,小程序则走微信/支付宝原生导航栏体系,两者压根不读 pages.json 里的 titleNView 配置。
- 真机调试时 H5 或小程序里看到按钮,一定是误用了自定义 DOM 元素(比如
<view></view>浮在顶部),但那根本不是“原生导航栏按钮”,也不响应onNavigationBarButtonTap - 小程序端若想右侧有按钮,必须隐藏原生导航栏(
"navigationStyle": "custom"),自己画一个,并手动对齐胶囊按钮位置 - App 端若漏写
#ifdef APP-PLUS条件编译,会导致非 App 端构建报 warning,但不会 crash,容易误以为“看起来正常”
pages.json 中正确配置 buttons 数组
按钮必须定义在对应页面的 style.app-plus.titleNView.buttons 下,且路径需严格匹配;图标不能用网络地址或 base64,必须是本地 .ttf 字体文件路径(如 /static/iconfont.ttf),并配合 text + fontSize + color 使用。
-
float: "right"才会出现在右侧;"left"会挤到左上角,可能遮挡返回箭头 - 每个 button 对象至少要有
text或type(如"type": "close");纯图标按钮推荐用type,避免字体加载失败导致空白 -
fontSize单位必须带px(如"16px"),不支持rpx或无单位数字 - 多个按钮按数组顺序从左到右排列,但 iOS 上最多显示两个,Android 通常支持三个
监听点击必须写在页面生命周期里
按钮点击事件不会触发普通 @click,也不能用 methods 里随便定义函数——必须靠页面级生命周期钩子 onNavigationBarButtonTap 捕获,且该函数必须导出在 export default 的 options 对象中。
- 函数名拼错(比如写成
onNavigationButtonTap)或放在methods里,都会静默失效 - 参数是数组,每个元素含
index(对应buttons数组下标),可据此区分不同按钮:uni.navigateTo({ url: '/pages/xxx' }) - App 端若同时用了
web-view,且在 web-view 页面里调用$getAppWebview().setStyle()动态改titleNView,必须确保当前页面实例存在、webview 实例已 ready,否则设置无效
常见错误:以为“自定义 DOM = 原生按钮”
很多开发者在页面里写一个 <view class="nav-right"><button>分享</button></view> 并加 position: fixed; top: 0; right: 0;,再配个 @click——这在 H5 和小程序里能点,但在 App 端实际运行时,这个 DOM 元素和原生导航栏不在同一层级,会被原生标题栏盖住,或者被系统状态栏裁切,真机上根本点不到。
- 这种写法在 H5 小程序模拟器里“看起来像”,但一上真机就失效,尤其 iPhone X 及以上机型因安全区域偏移更明显
- 如果项目要多端统一,别硬扛
titleNView,直接全局设"navigationStyle": "custom",所有端都走自定义导航栏逻辑,反而更可控 - App 端启用
titleNView后,navigationBarTitleText会自动失效,标题得靠titleNView.titleText控制,这点常被忽略
最易被忽略的一点:iOS 真机上,titleNView.buttons 的 color 属性对 type: "close" 无效,关闭按钮颜色由系统控制,只能通过 backgroundColor 和整体 titleNView 样式间接影响视觉效果。











