鸿蒙开发(二)arkweb的使用注意事项

在鸿蒙应用开发中,WebView 依然是绕不开的能力

无论是 H5 活动页、配置化页面,还是业务兜底方案,Web 都扮演着重要角色。

鸿蒙官方虽然提供了 WebView 能力,但在实际项目中,直接使用原生能力往往不够顺手,例如:

  • JS 交互方式分散、不统一
  • Web 生命周期与页面路由难以协同
  • 参数传递、标题管理、返回逻辑重复
  • Web 参数配置容易踩坑(尤其是 mixedMode)

因此,本文基于官方组件 @pura/harmony-web,结合实际业务场景,进行了二次封装与工程化改造,并总结了一些关键设计点与注意事项。

原始组件地址:
https://ohpm.openharmony.cn/#/cn/detail/@pura%2Fharmony-web


一、整体设计目标

本次封装的目标并不是"再造 WebView",而是解决真实业务中的常见问题

  • 统一 Web 页面路由承载方式
  • 统一 JS ↔ Native 交互模型
  • 控制 Web 参数配置的"自由度",避免误用
  • 让 Web 页面像普通 ArkUI 页面一样可控、可维护

最终希望做到的是:

Web 页面只是一个特殊的页面,而不是一个"特殊系统"


二、封装基础:基于 harmony-web 的二次开发

博主本次并未直接使用底层 webview.WebviewController + 原生组件拼装,而是:

  • @pura/harmony-web 为基础
  • 在其之上做二次封装和能力收敛
  • 对外仅暴露必要参数和交互接口

这样做的好处是:

  • 避免直接操作大量 Web 细节
  • 保证项目内 Web 行为的一致性
  • 后续替换或升级 Web 内核成本更低

三、Web 与 JS 交互:多参数调用的正确姿势

在 Web 与 Native 的交互中,一个非常常见的需求是:

👉 从 Native 主动调用 JS 方法,并传递多个参数

正确的做法

如果 JS 方法需要多个参数,推荐通过字符串拼接 + 标准 JS 调用形式

复制代码
const trainJsCmd = `getToken('${token}', '${apiVersion}')`
this.runJavaScript(trainJsCmd)
  .then((data) => {
    // JS 执行成功回调
  })
  .catch((error: Error) => {
    // JS 执行失败处理
  })

这样设计的原因

  • WebView 本质是执行 JS 字符串
  • 多参数场景下,显式构造函数调用最直观
  • 避免 JSON 序列化 / 反序列化带来的兼容性问题

⚠️ 实践经验:

不要幻想 WebView 能帮你"智能解析参数",一切都要明确、可控。


四、mixedMode:一个非常容易被滥用的配置

在 WebView 配置中,mixedMode 是一个高风险参数

很多开发在遇到资源加载异常时,会下意识设置:

复制代码
mixedMode: MixedMode.All

强烈建议:请勿乱用 mixedMode

原因很简单:

  • mixedMode 会放开 HTTPS 页面加载 HTTP 资源
  • 存在安全风险
  • 在部分系统版本上,会引发资源加载异常或不可预期行为

✅ 正确做法是:

  • 优先保证 H5 资源本身的协议一致性
  • 只有在明确知道后果的前提下才调整 mixedMode
  • 不在基础封装层默认开启

基础组件的职责是"兜底",不是"纵容错误配置"


五、页面自适应:缩放到适配屏幕的关键配置

在实际项目中,H5 页面经常出现:

  • 字体过大 / 过小
  • 页面无法完整适配屏幕
  • 看起来像"放大版网页"

在 ArkWeb 中,如果希望页面自适应屏幕比例,需要注意两个关键配置:

复制代码
this.options.initialScale = 0
this.options.textZoomRatio = 0

这两个参数的意义

  • initialScale = 0:让 WebView 自行计算初始缩放比例
  • textZoomRatio = 0:关闭额外的文本缩放干预

这是一个组合配置 ,缺一不可。

只设置其中一个,往往效果不完整。


六、核心页面结构设计

下面是本次封装后的 Web 页面核心结构(已做工程化整合):

关键设计点说明

  • 使用 @Route 承载 Web 页面,纳入统一路由体系
  • Web 页面与普通 ArkUI 页面拥有一致的:
    • 返回逻辑
    • 标题管理
    • 生命周期控制
  • JS 对象通过 arkJsObject 注入
  • WebClient 统一处理标题、加载事件

核心代码结构(节选)

复制代码
@Route({ name: RouterConst.PAGE_WEB_VIEW })
@ComponentV2
export struct WebViewPage {
  private webviewVM: WebViewPageVM = new WebViewPageVM()
  private webviewController: WebviewController = new webview.WebviewController()

  @Local webUrl: string = ""
  @Local options: ArkWebOptions = new ArkWebOptions()
  @Local webClient: MyWebClient = new MyWebClient()
  @Local private jsObject: WebJsObj = new WebJsObj()

  aboutToAppear(): void {
    // 读取路由参数
    // Web 配置
    this.options.fileAccess = true
    this.options.databaseAccess = true
    this.options.allowWindowOpenMethod = true
    this.options.initialScale = 0
    this.options.textZoomRatio = 0
  }

  build() {
    ComNavDestination({
      baseVM: this.webviewVM,
      onBackPress: () => this.onBackController()
    }) {
      Column() {
        ArkWeb({
          controller: this.webviewController,
          src: this.webUrl,
          options: this.options,
          webClient: this.webClient,
          arkJsObject: this.jsObject
        })
      }
    }
  }
}

七、返回逻辑:Web 优先,页面兜底

在返回逻辑上,采用了一个非常明确的原则:

能 Web 内返回,就不直接退出页面

复制代码
private onBackController(): boolean {
  if (this.webviewController?.accessBackward()) {
    this.webviewController.backward()
    return true
  }
  return false
}

这样可以保证:

  • H5 内部页面栈完整
  • 用户体验符合直觉
  • 不会误触返回直接退出页面

八、经验总结与注意事项

1️⃣ Web 封装不是功能堆砌

基础 Web 组件一定要:

  • 克制参数
  • 限制能力
  • 默认安全

2️⃣ JS 交互要"笨一点"

  • 明确字符串调用
  • 明确参数顺序
  • 明确回调结果

3️⃣ Web 配置越少越稳定

  • mixedMode 不要默认开
  • 缩放、缓存等行为统一管理
  • 不允许业务层随意修改底层配置

九、总结

通过基于 @pura/harmony-web 的二次封装,我们可以:

  • 将 Web 页面真正纳入 ArkUI 工程体系
  • 提供稳定、可控、可维护的 Web 能力
  • 避免项目后期 Web 页面失控

WebView 并不复杂,
复杂的是缺乏约束的使用方式

当 Web 被当成"普通页面"来设计时,

很多问题,反而自然就消失了。

相关推荐
麟听科技15 小时前
HarmonyOS 6.0+ APP智能种植监测系统开发实战:农业传感器联动与AI种植指导落地
人工智能·分布式·学习·华为·harmonyos
前端不太难15 小时前
HarmonyOS PC 焦点系统重建
华为·状态模式·harmonyos
空白诗16 小时前
基础入门 Flutter for Harmony:Text 组件详解
javascript·flutter·harmonyos
lbb 小魔仙17 小时前
【HarmonyOS】React Native实战+Popover内容自适应
react native·华为·harmonyos
motosheep17 小时前
鸿蒙开发(四)播放 Lottie 动画实战(Canvas 渲染 + 资源加载踩坑总结)
华为·harmonyos
左手厨刀右手茼蒿18 小时前
Flutter for OpenHarmony 实战:Barcode — 纯 Dart 条形码与二维码生成全指南
android·flutter·ui·华为·harmonyos
lbb 小魔仙18 小时前
【HarmonyOS】React Native of HarmonyOS实战:手势组合与协同
react native·华为·harmonyos
果粒蹬i19 小时前
【HarmonyOS】React Native实战项目+NativeStack原生导航
react native·华为·harmonyos
waeng_luo19 小时前
HarmonyOS 应用开发 Skills
华为·harmonyos
石去皿19 小时前
分布式原生:鸿蒙架构哲学与操作系统演进的范式转移
分布式·架构·harmonyos