uni-app 动态设置导航栏标题:uni.setNavigationBarTitle API 使用详解与跨端实现原理
【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址: https://gitcode.com/gh_mirrors/un/uni-app
uni.setNavigationBarTitle是 uni-app 框架中用于动态修改当前页面导航栏标题的官方 API,在 uni-app x 中同样以 UTS 插件形式内置提供。本文以本仓库 docs/api/set-navigation-bar-title.md 为骨架,结合 src/uni_modules/uni-navigationBar 的协议层与平台层实现源码,系统讲解该 API 的参数、回调、返回值、错误码、完整示例以及底层跨端实现原理,帮助你在一套代码中为 Web、小程序、App(Android/iOS)与 HarmonyOS 动态切换页面标题。
一、API 概述:动态设置当前页面的标题
uni.setNavigationBarTitle(options)的作用是动态设置当前页面的标题,即运行时覆盖在 pages.json 中通过navigationBarTitleText配置的静态标题。它常用于以下场景:
- 详情页根据后端返回的数据动态展示标题(如商品名、文章标题);
- 页面标题中包含用户输入或查询关键词;
- 同一页面在不同上下文下复用并展示不同标题。
需要强调的是,该 API 处理的是页面栈的栈顶页面,而非调用代码所在页面,这一点在“八、重要语义”中会结合官方说明与源码详细展开。
二、跨端兼容性
依据原文档与 interface.uts 中的@uniPlatform标注,uni.setNavigationBarTitle在以下平台的兼容版本如下:
| Web | 微信小程序 | Android | iOS | HarmonyOS | | :- | :- | :- | :- | :- | | 4.0 | 4.41 | 3.97 | 4.11 | 4.61 |
接口层标注同时给出了更多的平台差异细节(来自 interface.uts):
- App 端:Android 自 unixVer 3.97、iOS 自 4.11、HarmonyOS 自 4.61(uniVer 4.23、unixVaporVer 5.0)起支持;
- 小程序端:微信(hostVer √、uniVer √、unixVer 4.41)、支付宝、百度、抖音、飞书、QQ、快手、京东等均有支持标注,其中支付宝/百度/抖音/QQ/快手/京东等在 unixVer 列标注为
x,表示 uni-app x 版本暂未开放该能力; - Web 端:uni-app x 自 4.0 起支持;
- 快应用(quickapp):标注为
x,不支持。
三、参数详解
调用方式为uni.setNavigationBarTitle(options),其中options为必填的SetNavigationBarTitleOptions类型对象。
options 的属性描述
| 名称 | 类型 | 必备 | 描述 | | :- | :- | :- | :- | | title | string | 是 | 页面标题 | | success | (result: SetNavigationBarTitleSuccess) => void | 否 | 接口调用成功的回调函数 | | fail | (error: SetNavigationBarTitleFail) => void | 否 | 接口调用失败的回调函数 | | complete | (res: SetNavigationBarTitleComplete) => void | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
各回调的详细类型定义可在 interface.uts 中确认:SetNavigationBarTitleOptions中的title是唯一必填属性,success/fail/complete均为可选回调,且接口签名统一为(options: SetNavigationBarTitleOptions) => void。
title:页面标题
title为 string 类型,必填。原文档示例中演示了普通标题与超长标题两种用法,说明该参数没有长度限制(展示效果由各平台导航栏自身决定,超长标题在不同端可能被截断或缩小字号,请以实际渲染为准)。
回调返回值属性
三个回调均携带errMsg: string:
- SetNavigationBarTitleSuccess:
{ errMsg: string }(必备); - SetNavigationBarTitleComplete:
{ errMsg: string }(必备); - SetNavigationBarTitleFail:除
errMsg外,还包含错误码等字段(详见第五节)。
在 interface.uts 中,SetNavigationBarTitleSuccess实际被定义为AsyncApiSuccessResult、SetNavigationBarTitleComplete被定义为AsyncApiResult,它们是框架异步 API 的统一结果类型,进一步印证了本 API 遵循 uni-app x 标准的异步接口约定。
四、返回值与 Promise
接口声明的返回值类型为:
| 类型 | 必备 | | :- | :- | | Promise<SetNavigationBarTitleSuccess> | 否 |
即该 API 同时支持回调风格(传入success/fail/complete)与Promise 风格(await uni.setNavigationBarTitle(...))。Promise 成功后的 resolve 值同样为{ errMsg: string }。需要说明的是,在 interface.uts 中其函数类型签名为(options: SetNavigationBarTitleOptions) => void,而 Uni 接口声明为Promise<SetNavigationBarTitleSuccess> | null,在实际工程中按 Promise 或回调两种风格使用均可。
五、错误处理与错误码
失败回调fail中携带的错误对象SetNavigationBarTitleFail结构如下:
| 名称 | 类型 | 必备 | 描述 | | :- | :- | :- | :- | | errCode | number | 是 | 设置导航栏标题错误码
- 4: 框架内部异常 | | errSubject | string | 是 | 统一错误主题(模块)名称 | | data | any | 否 | 错误信息中包含的数据 | | cause | Error | 否 | 源错误信息,可以包含多个错误 | | errMsg | string | 是 | 错误描述 |
该错误类型继承自框架统一的 UniError 错误体系。在源码层面,interface.uts 将SetNavigationBarTitleErrorCode定义为字面量类型4,unierror.uts 中的SetNavigationBarTitleFailImpl直接继承UniError并默认errCode = 4,从而保证所有失败回调都能拿到符合规范的结构化错误对象。
六、完整示例:从文档示例到仓库实战页面
原文档给出的示例即 hello uni-app x 系列的官方演示页,本仓库对应的实战页面位于 src/pages/API/set-navigation-bar-title/set-navigation-bar-title.uvue,并在 src/pages.json 中通过以下配置注册(静态标题为uni.setNavigationBarTitle | 设置导航条标题):
{ "path": "pages/API/set-navigation-bar-title/set-navigation-bar-title", "group": "1,2,3", "style": { "navigationBarTitleText": "uni.setNavigationBarTitle | 设置导航条标题" } }页面模板包含三个核心操作按钮:设置新标题、设置超长标题,以及 HarmonyOS 专属的标题 loading 显隐(通过#ifdef APP-HARMONY条件编译控制):
<template> <page-head title="setNavigationBarTitle"></page-head> <view class="uni-padding-wrap uni-common-mt"> <button @tap="setNavigationBarNewTitle" class="uni-btn"> 设置当前页面标题为: {{ newTitle }} </button> <button @tap="setNavigationBarLongTitle" class="uni-btn"> 设置超长标题 </button> <!-- #ifdef APP-HARMONY --> <button @tap="showNavigationBarLoading" class="uni-btn"> 设置标题 loading </button> <button @tap="hideNavigationBarLoading" class="uni-btn"> 隐藏标题 loading </button> <!-- #endif --> </view> </template>基础用法:动态设置普通标题
<script setup lang="uts"> const newTitle = ref('new title') const setNavigationBarNewTitle = () => { uni.setNavigationBarTitle({ title: newTitle.value, success: () => { console.log('setNavigationBarTitle success') }, fail: () => { console.log('setNavigationBarTitle fail') }, complete: () => { console.log('setNavigationBarTitle complete') } }) } </script>进阶用法:设置超长标题
<script setup lang="uts"> const longTitle = ref('long title long title long title long title long title long title long title long title long title long title') const setNavigationBarLongTitle = () => { uni.setNavigationBarTitle({ title: longTitle.value, success() { console.log('setNavigationBarTitle success') }, fail() { console.log('setNavigationBarTitle fail') }, complete() { console.log('setNavigationBarTitle complete') } }) } </script>HarmonyOS 专属:标题 loading 显示与隐藏
示例页面中还通过uni.showNavigationBarLoading/uni.hideNavigationBarLoading演示了导航栏加载动画(仅在 APP-HARMONY 下编译生效,且在VUE3-VAPOR编译模式下被排除):
<script setup lang="uts"> // #ifdef APP-HARMONY const showNavigationBarLoading = () => { uni.showNavigationBarLoading({ success: () => console.log('showNavigationBarLoading success'), fail: () => console.log('showNavigationBarLoading fail'), complete: () => console.log('showNavigationBarLoading complete') }) } const hideNavigationBarLoading = () => { uni.hideNavigationBarLoading({ success: () => console.log('hideNavigationBarLoading success'), fail: () => console.log('hideNavigationBarLoading fail'), complete: () => console.log('hideNavigationBarLoading complete') }) } // #endif </script>七、源码级实现原理:协议校验与平台分发
该 API 的官方实现以 UTS 插件uni-navigationBar形式内置,核心文件组织如下(目录结构来自 src/uni_modules/uni-navigationBar):
utssdk/protocol.uts:参数协议(校验规则)层;utssdk/interface.uts:类型定义与 Uni 接口声明;utssdk/unierror.uts:错误对象实现;utssdk/app-android/index.uts:Android 平台实现;utssdk/app-harmony/index.uts:HarmonyOS 平台实现。
协议层:title 为必填 string
protocol.uts 中定义了API_SET_NAVIGATION_BAR_TITLE = 'setNavigationBarTitle',并通过SetNavigationBarTitleProtocol声明了唯一参数规则:
export const SetNavigationBarTitleProtocol = new Map<string, ProtocolOptions>([ [ 'title', { type: 'string', required: true } ] ])也就是说,框架在正式调用平台实现前,会先依据该协议对入参做类型与必填校验,title缺省或非 string 会被协议层拦截。
Android 平台实现:更新原生页面样式
app-android/index.uts 通过defineAsyncApi定义异步 API,核心流程是:
- 通过
getCurrentPages()取页面栈,并以pages[pages.length - 1]定位栈顶页面; - 若栈为空则
res.reject(new SetNavigationBarTitleFailImpl('page is not ready')),即走到fail回调并携带错误码 4; - 否则通过
currentPage.vm!.$nativePage拿到原生页面对象,调用updateStyle更新navigationBarTitleText样式键:const appPage = currentPage.vm!.$nativePage appPage!.updateStyle( new Map<string, any | null>([ ['navigationBarTitleText', options.title], ]), ) - 更新成功后
res.resolve(null)触发success。
可见 Android 端标题更新本质上是把标题写回原生页面(UniPage)的样式表,与 pages.json 静态配置共用同一navigationBarTitleText键。
HarmonyOS 平台实现:基于 Webview titleNView
app-harmony/index.uts 中,HarmonyOS 端同样先取getCurrentPages()栈顶页面,然后通过page.$getAppWebview()获取 Webview,读取现有titleNView样式并更新titleText:
const webview = getWebview(page) if (webview) { const style = webview.getStyle() if (style && style.titleNView) { webview.setStyle({ titleNView: { titleText: args.title, } as TitleNView, } as PlusWebviewWebviewTitleNViewStyles) } executor.resolve() } else { executor.reject() }值得注意的源码细节:该文件内setNavigationBarTitle上方有一行注释// NOTE x 和 非 x 都不使用,说明此段基于 WebviewtitleNView的实现可能并非当前版本的主分发路径,具体是否生效取决于编译器平台适配层对鸿蒙 Webview 的接管方式,实际使用请以对应 HBuilderX 版本的运行结果为准。
八、重要语义:操作的是页面栈栈顶页面
原文档 Tips 明确提示:本 API 默认处理页面栈栈顶页面,而不是代码所在页面,详见 docs/api/README.md 的 “uni对象的API与页面的关系” 一节。这一点与源码实现完全吻合——Android 与 HarmonyOS 实现均通过getCurrentPages()并取pages[pages.length - 1]来定位目标页面。
由此带来的两个典型陷阱(README 原文示例):
- 在新页面
onShow触发之前调用该 API,由于新页面尚未展示,此时逻辑层找到的栈顶页面仍是上一个页面,标题会被设置到上一页; - 在定时器中调用该 API,随后又打开了新页面,但旧页面定时器仍在运行——API 一直在找栈顶页面,新页面
onShow后定时器就会开始改新页面的标题。
因此在真实业务中,如需确保修改的是“当前正在显示的页面”,建议在页面onShow之后或在用户交互事件(如@tap)中调用,避免异步定时器导致标题错位。
九、配套 API 与最佳实践
uni-navigationBar插件还同时实现了同族 API,便于统一管理导航栏表现:
- uni.setNavigationBarColor:设置导航栏前景色与背景色(protocol.uts 中
frontColor仅允许#ffffff/#000000两个取值,并内置校验器); - uni.showNavigationBarLoading / uni.hideNavigationBarLoading:显示/隐藏导航栏加载动画(HarmonyOS 与各小程序平台支持,详见 interface.uts)。
实战建议总结:
- 静态标题优先在 pages.json 的页面
style.navigationBarTitleText中声明,运行时需要变化时再调用uni.setNavigationBarTitle; - 标题来自网络请求时,建议在数据返回后、页面可见期间调用,并配合
success/fail/complete做好结果日志与状态维护; - 若需频繁在页面间跳转并恢复标题,可在
onShow中统一设置,保证标题与页面内容始终一致; - 涉及跨端差异(如 HarmonyOS 的标题 loading)时,使用条件编译精确控制平台行为。
通过本文的说明,你可以基于 docs/api/set-navigation-bar-title.md 的接口规范与 src/uni_modules/uni-navigationBar 的源码,快速掌握uni.setNavigationBarTitle的完整用法、错误处理与跨端实现机制,并在自己的 uni-app / uni-app x 工程中直接落地。
【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址: https://gitcode.com/gh_mirrors/un/uni-app
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考