HarmonyOS 7 · ArkWeb 混合应用开发手记 04
混合页面最容易做出"看起来没问题,用起来很怪"的地方,就是返回键。H5从列表进详情,再进活动页。用户按一次返回,直觉上应该先退回上一张网页;如果你直接router.back(),整个 ArkWeb 页面都没了。
所以这一篇只解决一件事:把 Web 历史栈和原生导航栈分开。
1. 两个栈不是一个栈
ArkUI 有自己的页面导航,Web 内部也有浏览历史。返回时先问Web:"你自己还能不能退?"
ts
private handleBack(): boolean {
if (this.controller.accessBackward()) {
this.controller.backward()
return true
}
return false
}
实际 API 名称请以 HarmonyOS 7 当前 SDK类型提示为准。关键不是背名字,而是这个判断顺序。
【配图 01:Web History 与 ArkUI Navigation 两层返回栈示意】
2. 返回策略应该明确
我通常定成:
text
Web 有历史 → Web 后退
Web 无历史 → ArkUI 页面退出
特殊业务页 → 按业务规则处理
不要把规则散在按钮、手势和系统返回回调三个地方。
3. 页面内返回按钮也走同一个函数
ts
Button('返回')
.onClick(() => {
if (!this.handleBack()) {
this.exitPage()
}
})
这样标题栏返回和系统返回不会出现两个行为。
4. 重定向会污染历史吗
登录、OAuth、中转页经常产生一串历史记录。用户按返回时可能又回到中转页。
这类页面最好在 H5 路由层使用替换语义,或者在原生侧明确哪些 URL
不应该成为用户可见历史节点。

5. H5 SPA 更特殊
Vue/React 这类 SPA 可能只改 History API,并没有真正加载新文档。所以不能只看 onPageBegin次数判断"页面层级"。
H5 最好把路由变化主动通知原生:
js
NativeBridge.invoke(JSON.stringify({
method: 'routeChanged',
params: { path: location.pathname }
}))
原生侧只记录必要状态,不要接管 H5 的全部路由。
6. 登录页退出规则要单独想
例如用户从商品页跳登录,登录完成后通常希望回商品,而不是返回登录页。这里不是WebView API 能替你决定的,是业务导航策略。
7. 防止连续点击
ts
@State private backing: boolean = false
处理返回前做短暂保护,避免用户快速点两次造成 Web 和原生同时 pop。
8. 日志记录当前 URL
ts
console.info(`[WebBack] current=${this.currentUrl}`)
返回问题最难复现,URL 和来源页必须留下。
9. 外链不要随便塞进当前历史
帮助中心、协议、第三方活动是否应该在当前 Web容器打开,要先定义。否则返回栈会越来越不可控。
10. 小结
返回键不是一个 back() 就结束。正确的思路是先区分 Web 历史和 ArkUI导航,再统一入口、处理 SPA、重定向和业务特殊页。
下一篇继续做用户最容易感知的能力:H5点"上传图片"以后,怎么把选择文件、相册和权限接到 HarmonyOS 7。