需在pages.json的style.app-plus.titleNView.buttons数组中写两个对象,顺序决定右对齐后的从右到左排列;e.index可区分点击按钮,仅APP-PLUS生效,H5/小程序需条件编译DOM模拟。

pages.json 里 buttons 数组要写两个对象
uni-app 原生导航栏右侧放两个按钮,本质就是往 pages.json 对应页面的 style.app-plus.titleNView.buttons 数组里塞两个配置对象。顺序决定渲染顺序——数组靠前的按钮更靠右,后一个会紧贴它左边(不是并排居中,是「右对齐后依次左排」)。
常见错误是只写了一个对象、或漏了逗号导致 JSON 解析失败,App 启动时直接不显示按钮;也有人误以为要加 float: "right" 到每个按钮上——其实不用,整个 buttons 区域默认右对齐,每个按钮只控制自身样式。
- 必须用数组,不能是单个对象:
"buttons": [{...}, {...}] - 两个按钮都设
float: "right"会报错(该字段只在 buttons 外层生效,不支持单个按钮设) - 图标按钮记得
text设为空字符串"",否则文字和图标会叠在一起 - 字体图标路径必须是本地
.ttf文件,且路径以/开头(如/static/iconfont.ttf),相对路径无效
onNavigationBarButtonTap 怎么区分点击的是哪个按钮
onNavigationBarButtonTap 回调参数 e 是个对象,关键字段是 e.index,值为 0 或 1 —— 完全对应 buttons 数组的下标。别试图用 e.text 或 e.button 判断,这些字段不存在。
容易踩的坑是:在 H5 或小程序环境也写了这个函数,但实际不会触发(因为 titleNView 仅 app-plus 生效),结果调试时发现点不动,其实是平台没走这套逻辑。
- 判断逻辑直接写
if (e.index === 0) { /* 第一个按钮 */ },别用== - 不要在回调里访问
this.xxx,尤其在页面刚加载时,this可能还没初始化完成 - 跳转统一用
uni.navigateTo,不用this.$router.push(后者在某些安卓机型上静默失败)
两个按钮间距太小或重叠?改 width 或 fontSize
原生导航栏按钮没有 margin/padding 概念,间距由 width 和 fontSize 共同影响。如果两个按钮挤在一起,优先调大 width(单位建议用 px,rpx 在原生层表现不稳定);若文字/图标被截断,就调 fontSize 并同步微调 width。
注意:iOS 和 Android 对 width 的解析略有差异,Android 更“抠”,同样数值下 iOS 显示更宽松。真机测试比模拟器可靠得多。
- 纯文字按钮:设
width: "60px"+fontSize: "15px"通常够用 - 图标按钮:
width: "44px"+fontSize: "22px"是较稳妥的组合 - 避免设
width小于 36px,部分低端安卓机可能无法响应点击
H5 和小程序怎么兼容?只能手动加 DOM 按钮
titleNView.buttons 在 H5 和小程序端完全不生效,也不会触发 onNavigationBarButtonTap。想保持一致体验,必须在页面 DOM 里额外放两个 或 ,用 CSS 定位到右上角,并监听 click 事件。
这里最容易被忽略的是状态同步:App 端按钮样式可动态改(用 currentWebview.setTitleNViewButtonStyle),但 H5 端得自己维护按钮文本、禁用态、颜色等,两套逻辑要独立处理,不能共用同一份 data。
- 推荐用
#ifdef APP-PLUS/#ifndef APP-PLUS条件编译隔离逻辑 - H5 端按钮定位依赖
statusBarHeight和胶囊按钮位置,必须用uni.getMenuButtonBoundingClientRect()计算真实 top 值 - 别忘了给 H5 按钮加
z-index,否则可能被内容遮住
多按钮场景下最麻烦的不是配置,而是跨平台状态同步和点击热区校准——App 端按钮位置固定,H5 端却随屏幕尺寸和系统 UI 变化,每次发版前务必在 iOS、Android、微信小程序、H5 四端真机点一遍。











