写点什么

《HarmonyOSNext Web 组件双向通信开发指南:JavaScript 互调 + 动态注册 + 跨端数据流转实战》

作者:Turing_010
  • 2025-06-14
    广东
  • 本文字数:2974 字

    阅读完需:约 10 分钟

《HarmonyOSNext Web组件双向通信开发指南:JavaScript互调+动态注册+跨端数据流转实战》

《HarmonyOSNext Web 组件双向通信开发指南:JavaScript 互调+动态注册+跨端数据流转实战》

##Harmony OS Next ##Ark Ts ##教育


本文适用于教育科普行业进行学习,有错误之处请指出我会修改。

🚀 一、应用侧如何调用前端 JS 函数?

应用侧有两种神器可以调用前端页面的 JavaScript 函数:runJavaScript() 和它的升级版 runJavaScriptExt()!两者的核心区别是:


  • runJavaScript():只能传字符串类型的脚本

  • runJavaScriptExt()更强更灵活!支持字符串和二进制数据(ArrayBuffer),还能用 AsyncCallback 异步获取结果!


📌 举个栗子:点击应用按钮让前端字体变绿!当我们在应用侧点击"runJavaScript"按钮时,触发前端页面的htmlTest()方法:

💻 前端页面代码

<!-- index.html --><!DOCTYPE html><html><body><button type="button" onclick="callArkTS()">点我变魔术!</button><h1 id="text">原始黑色文字👉调用runJavaScript变绿🍀,runJavaScriptCodePassed变红🔥</h1><script>    // 有参函数调用    var param = "从ArkTS发来的消息:Hi JS!";    function htmlTest(param) {        document.getElementById('text').style.color = 'green';        console.log(param); // 控制台打印参数    }
// 无参函数调用(和上面是同一个函数名演示不同场景) function htmlTest() { document.getElementById('text').style.color = 'green'; }
// 按钮触发桥接函数 function callArkTS() { changeColor(); }</script></body></html>
复制代码

⚙️ 应用侧 ArkTS 代码

// WebComponent.etsimport { webview } from '@kit.ArkWeb';
@Entry@Componentstruct WebComponent { controller: webview.WebviewController = new webview.WebviewController();
aboutToAppear() { // 开启Web调试模式(重要!) webview.WebviewController.setWebDebuggingAccess(true); }
build() { Column() { Button('runJavaScript') .onClick(() => { // 调用无参版:去掉param this.controller.runJavaScript('htmlTest()'); }) Button('runJavaScriptCodePassed') .onClick(() => { // 直接注入JS代码片段 this.controller.runJavaScript( `function changeColor(){ document.getElementById('text').style.color = 'red' }` ); }) // 加载本地HTML页面 Web({ src: $rawfile('index.html'), controller: this.controller }) } }}
复制代码



🔌 二、注册应用侧方法到前端

想让前端页面调用应用侧的方法?我们需要把 ArkTS 方法"注入"到前端!有两种神操作:

方式 1:初始化时注册(超省心!)

// 初始化注册版.etsimport { webview } from '@kit.ArkWeb';
// 要注册的测试类class TestAgent { test(): string { return 'ArkTS发来的问候!'; }}
@Entry@Componentstruct WebComponent { controller: webview.WebviewController = new webview.WebviewController(); @State agent: TestAgent = new TestAgent(); // 注册对象
build() { Column() { Button('卸载代理') .onClick(() => { this.controller.deleteJavaScriptRegister("agentName"); }) Web({ src: $rawfile('index.html'), controller: this.controller }) // 核心注入操作! .javaScriptProxy({ object: this.agent, name: "agentName", // 前端通过该名称调用 methodList: ["test"], // 暴露的方法 controller: this.controller }) } }}
复制代码

方式 2:动态注册(灵活但需手动刷新)

// 动态注册版.etsimport { webview } from '@kit.ArkWeb';
class DynamicAgent { greet(): string { return "ArkUI动态注册示例"; }}
@Entry@Componentstruct Index { controller: webview.WebviewController = new webview.WebviewController(); @State agent: DynamicAgent = new DynamicAgent();
build() { Column() { Button('刷新页面') .onClick(() => { this.controller.refresh(); // 注册后必须刷新生效! }) Button('注册到前端') .onClick(() => { // 动态注册关键操作 this.controller.registerJavaScriptProxy( this.agent, "dynamicAgent", ["greet"] // 暴露的方法名 ); }) Web({ src: $rawfile('index.html'), controller: this.controller }) } }}
复制代码


⚡ 重要提示:动态注册后必须执行.refresh() 才能生效!



🧩 三、参数传递实战宝典

场景 1:传递数组对象

// ArkTS侧class ArrayAgent {  getNumbers(): number[] {    return [1, 3, 5, 7];   }}<!-- 前端调用 --><script>function getData() {  const nums = testAgent.getNumbers();  console.log("收到数组:", nums); // [1,3,5,7]}</script>
复制代码

场景 2:传递自定义对象

// 定义学生对象class Student {  name: string = '';  age: number = 0;}
class StudentAgent { getStudent(): Student { return { name: "小明", age: 18 }; }}<script>function showStudent() { const stu = studentAgent.getStudent(); alert(`姓名:${stu.name},年龄:${stu.age}`);}</script>
复制代码

场景 3:双向回调神操作

// ArkTS接收JS回调class CallbackAgent {  handle(callback: (data:string) => void) {    setTimeout(() => callback("操作完成!"), 1000);  }}<script>testAgent.handle((result) => {  console.log("回调结果:", result); });</script>
复制代码



🔄 四、Promise 异步交互

方式 1:ArkTS 返回 Promise

class PromiseAgent {  fetchData(): Promise<string> {    return new Promise((resolve) => {      setTimeout(() => resolve("获取成功"), 1500);    });  }}<script>promiseAgent.fetchData()  .then(data => console.log(data))  .catch(err => console.error(err));</script>
复制代码

方式 2:前端生成 Promise

<script>function asyncOperation() {  return new Promise((resolve) => {    testAgent.delayCallback(resolve);   });}
asyncOperation().then(() => { console.log("异步操作完成!");});</script>
复制代码



📊 避坑指南总结表


💡 终极提示:调试时务必开启 setWebDebuggingAccess(true),配合 Chrome DevTools 实时查看控制台输出!



🎯 关键要点总结

  1. 双向通信三剑客runJavaScript() ➡️ 基础调用javaScriptProxy() ➡️ 初始化注册registerJavaScriptProxy() ➡️ 动态注册(记得 refresh!)

  2. 数据传输四原则✅ 基础类型直接传✅ 对象用 Class 封装✅ 数组自动序列化✅ 函数通过回调传递

  3. 异步交互双通道Promise方案:适合明确操作结果的场景Callback方案:适合事件驱动型交互


最后放个彩蛋🥚:遇到permission配置头秃时,直接用官方提供的 JSON 模板改参数值就好啦!不需要自己造轮子~

用户头像

Turing_010

关注

还未添加个人签名 2025-05-22 加入

还未添加个人简介

评论

发布
暂无评论
《HarmonyOSNext Web组件双向通信开发指南:JavaScript互调+动态注册+跨端数据流转实战》_Turing_010_InfoQ写作社区