HarmonyOS Web 组件对话框(Web Dialog)实战:alertconfirmprompt 怎么接?怎么做得像“正常 App”?
HarmonyOS Web 组件对话框(Web Dialog)实战:alert/confirm/prompt 怎么接?怎么做得像“正常 App”?
鸿蒙第四期开发者活动
在 ArkTS 侧把异步逻辑包装成Promise,Native 侧拿到这个 Promise 对象,然后给它挂then / catch,在回调里获取异步结果或异常。
本文用一个完整示例,走一遍从 ArkTS 到 Native 的链路。
1. 整体思路
-
ArkTS 侧:
- 调用 Native 接口时,把一个 callback 传给 Native。
- Native 调用这个 callback,ArkTS 在 callback 里 返回一个 Promise 对象。
- Promise 内部用
setTimeout模拟异步,最终resolve或reject。
-
Native 侧:
- 通过
napi_call_function调用 ArkTS 传入的 callback,得到 Promise 对象。 - 用
napi_get_named_property拿到 Promise 的then和 `cat
- 通过
做 ArkWeb 的同学大概率都遇到过这种瞬间:
你把 H5 接进来了,页面跑得挺好,结果某天产品说:“这里点一下要弹个提示框(alert)/确认框(confirm)/输入框(prompt)。”
你心想:这不就是网页自带的吗?——然后你就发现:ArkWeb 并不会帮你把这些对话框自动弹出来。
官方文档说得很直白:ArkWeb 目前不提供默认网页对话框,如果 Web 页面调用了 alert/confirm/prompt,需要应用侧通过 onAlert/onConfirm/onPrompt 事件自己创建对话框来承接。华为开发者+1
这篇我就按“像人写的、能直接落地”的方式,把你真正需要的东西整理出来:
- Web 侧:什么时候会触发什么
- ArkTS 侧:怎么接
onAlert/onConfirm/onPrompt - 怎么用 ArkUI 的 Dialog 做出“像 App 一样”的弹窗
- 最容易踩坑的点(尤其是回调没处理好导致网页卡住)
1)先把底层逻辑搞明白:Web 触发、App 承接
在网页里,这三行大家都很熟:
alert('提示');
confirm('确定删除吗?');
prompt('请输入昵称');
但在 HarmonyOS 的 ArkWeb 里,这些不会自动弹系统弹窗。Web 触发后,控制权会交给应用侧:
alert()→ 触发onAlertconfirm()→ 触发onConfirmprompt()→ 触发onPrompt华为开发者+1
你需要在 ArkTS 里监听这些事件并创建弹窗,否则 Web 会“等回调等到怀疑人生”(用户看起来就是点了没反应)。
2)最推荐的实现方式:用 ArkUI 的 Dialog 承接网页弹窗
思路我建议你固定成一句话:
网页只负责发请求(alert/confirm/prompt),App 负责用原生 Dialog 做 UI,并把结果回传给 Web。
因为这样做出来的体验最像“真正的 App”,也方便你统一样式。
顺带一提:ArkWeb 的对话框回调对象/事件在 ArkWeb API 里有明确的接口定义。华为开发者+1
3)一套可复用的模板:onAlert / onConfirm / onPrompt 全接上
下面这段是“工程里最常用”的骨架(你复制后只需要替换 UI 细节):
ArkTS:Web 组件里监听对话框事件
import { webview } from '@kit.ArkWeb';
@Entry
@Component
struct WebDialogDemo {
private controller: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
Web({ src: $rawfile('web/dialog.html'), controller: this.controller })
.javaScriptAccess(true)
// 1) alert:只需要用户点“我知道了”
.onAlert((event) => {
// event.message:网页传来的提示文字(不同版本字段名以实际为准)
// event.result:你需要在用户点击后告诉 Web “已处理”
AlertDialog.show({
title: '提示',
message: event.message ?? '(无内容)',
confirm: {
value: '知道了',
action: () => {
// 关键:通知 Web 继续执行
event.result?.confirm?.();
}
}
});
return true; // 表示由应用侧处理
})
// 2) confirm:需要返回 true/false
.onConfirm((event) => {
AlertDialog.show({
title: '确认',
message: event.message ?? '确定继续?',
primaryButton: {
value: '取消',
action: () => event.result?.cancel?.()
},
secondaryButton: {
value: '确定',
action: () => event.result?.confirm?.()
}
});
return true;
})
// 3) prompt:需要返回输入内容(或取消)
.onPrompt((event) => {
// 简化写法:用 TextInput + 自己维护状态
let inputValue: string = event.defaultValue ?? '';
AlertDialog.show({
title: event.message ?? '请输入内容',
// 这里用自定义内容更舒服(CustomDialog 也可以)
// 为了示例简洁,用 message + 说明代替
message: '(示例)这里放一个 TextInput,输入后点击确定回传给 Web',
primaryButton: {
value: '取消',
action: () => event.result?.cancel?.()
},
secondaryButton: {
value: '确定',
action: () => event.result?.confirm?.(inputValue)
}
});
return true;
})
}
.padding(12)
}
}
为什么我强调 return true?
因为这代表“弹窗由应用侧处理”。官方文档里也明确强调需要通过这些回调自行创建对话框来承接。华为开发者+1
注:不同 API version 下事件对象字段名可能略有差异(例如 message/defaultValue/result 等),但整体机制是一致的:你必须在按钮点击时调用 result 的 confirm/cancel(以及 prompt 的 confirm(text))把结果回传给 Web。华为开发者+1
4)Web 侧测试页:三种弹窗一把梭
你放一个最小页面,方便自测:
<!doctype html>
<html>
<body>
<button onclick="alert('这是 alert 提示')">alert</button>
<button onclick="console.log(confirm('确定继续吗?'))">confirm</button>
<button onclick="console.log(prompt('请输入昵称', '程奕红'))">prompt</button>
</body>
</html>
跑起来后你就能直观看到:
- 点击按钮 → ArkTS 侧弹原生 Dialog
- 点“确定/取消” → Web 侧拿到返回值
5)几个“特别像人会踩”的坑(提前躲掉)
坑 A:弹窗出来了,但网页像“卡死”
九成是因为你没调用 event.result.confirm() / event.result.cancel()。
Web 在等你回信,它当然不会继续执行。
坑 B:prompt 输入框做得很丑/不好用
别硬用 AlertDialog 拼,实际项目里建议用 CustomDialog 做内容区(TextInput、校验提示、字数限制都更自然)。官方也有 ArkTS 自定义对话框(UIContext/CustomDialog)相关指导可参考。华为开发者+1
坑 C:样式不统一
我的建议:你在项目里封一个 WebDialogService:
- alert/confirm/prompt 统一从这里弹
- UI 样式、按钮文案、埋点、国际化都集中管理
后期你会感谢自己。
6)一句话收尾
HarmonyOS 的 Web Dialog 不是“网页自己弹”,而是“网页发请求,App 用原生弹窗承接并回传结果”。华为开发者+1
把这套机制吃透,你的 H5 才会真的像“嵌进 App 的业务页面”,而不是一块不受控的网页。

浙公网安备 33010602011771号