【HarmonyOS NEXT】Web 组件的基础用法以及 H5 侧与原生侧的双向数据通讯

 关键词:鸿蒙、ArkTs、Web组件、通讯、数据

官方文档Web组件用法介绍:文档中心

Web 组件加载沙箱中页面可参考我的另一篇文章:【HarmonyOS NEXT】 如何将rawfile中文件复制到沙箱中_鸿蒙rawfile 复制到沙箱-CSDN博客

目录

如何在鸿蒙应用中加载一个Web页面

一、加载网络地址页面

二、加载本地H5页面

实现Web组件H5层与应用层进行相互通讯

一、鸿蒙应用向H5页面发送数据

鸿蒙侧

H5侧

案例效果

二、H5页面向鸿蒙应用发送数据(附代码)

H5侧 (附代码)

鸿蒙侧(附代码)

案例效果

如何在鸿蒙应用中加载一个Web页面

一、加载网络地址页面

  1. 导入webview
import web_webview from **********'

  1. 创建WebviewController
controller: web_webview.WebviewController = new web_webview.WebviewController();

  1. 创建Web组件
Web({ src: "http://www.example.com/", controller: this.controller })

  1. 在module.json5中添加网络权限
"requestPermissions": [
    {
       "name": "ohos.permission.INTERNET"
    }
]

案例效果: 

​编辑​

二、加载本地H5页面

  1. 在项目的 rowfile 中存放 html 代码

​编辑​

  1. 在 Web组件 中使用 $rawfile 加载本地html
Web({ src: $rawfile('webTo.html'), controller: this.controller })

实现Web组件H5层与应用层进行相互通讯

一、鸿蒙应用向H5页面发送数据

在创建的WebviewController中使用 runJavaScript() 方法可直接触发 H5 页面中的方法

鸿蒙侧

​编辑​

同样也可以使用模板字符串拼接参数进行传参

​编辑​

H5侧

​编辑​

案例效果

​编辑​

二、H5页面向鸿蒙应用发送数据(附代码)

在原生代码侧使用 javaScriptProxy 方法向 h5 的 window 对象中注册方法,此处我注册的对象名叫 JSBridge ,在该对象中写入了一个 nativeMethod 方法,h5 中直接调用 nativeMethod() 方法即可向原生发送消息。

H5侧 (附代码)

h5侧直接调用 window 对象下的 JSBridge.nativeMethod 方法,第一个参数对应原生侧对应的 channelName 方法名,第二个参数为 h5 自定义参数,可带入回调方法,供原生侧完成调用的回调结果。

​编辑

附代码:

<!--
 * @Author: liuwei
 * @Date: 2023-12-18 15:14:22
 * @LastEditors: liuwei
 * @LastEditTime: 2023-12-18 15:23:40
 * @Description:
-->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <script src="./icsshosdk.js"></script>

    <style>
        body {
            padding-top: 80px;
        }

        .title {
            background: #eee;
            line-height: 60px;
            text-align: center;
            margin-bottom: 50px;
        }

        .button {
            cursor: pointer;
            line-height: 45px;
            color: #fff;
            border-radius: 10px;
            left: 20%;
            width: calc(100% - 30px);
            text-align: center;
            background: #616bff;
            margin: 15px;
        }

        .button:active {
            background: #525dff;
        }
    </style>

    <script>
        document.addEventListener('webActiveReceive', (e) => {
            console.log("luvi > " + JSON.stringify(e.detail));
            let { key, data } = JSON.parse(e.detail)
            switch (key) {
                case "changeBgColor":
                    document.getElementById("idt").style = "background: #ffecea;color: #ff7361"
                    break;
                case "changeBtColor":
                    document.querySelectorAll(".button").forEach(el => {
                        el.style = `background: ${data}`
                    })
                    break;
                default:
                    break;
            }
        })
    </script>

    <script>
        function openNativePage() {
            let params = {
                name: "LoginPage",
                success: function (res) {
                    console.log("luviWeb > openNativePage success. " + res)
                },
                fail: function () {
                    console.log("luviWeb > openNativePage fail.")
                }
            }
            window.JSBridge.nativeMethod("openNativePage", params)
        }

        function getCity() {
            let params = {
                success: function (res) {
                    document.getElementById("cityName").innerText = `当前城市:${res}`
                },
                fail: function () {
                    console.log("luviWeb > getCity fail.")
                }
            }
            window.JSBridge.nativeMethod("getCity", params)
        }
    </script>
</head>

<body>
    <div style="width: 100%;">
        <p class="title" id="idt">JSBridge演示</p>
        <div>
            <p class="button" onclick="openNativePage()">跳转原生页面</p>
        </div>
        <div style="margin-top: 30px;">
            <p style="margin-left: 15px;" id="cityName">当前城市:</p>
            <p class="button" onclick="getCity()">获取当前定位</p>
        </div>
    </div>
</body>

</html>

鸿蒙侧(附代码)

​编辑

附代码:

import { webview } from **********';

export interface IParamsCallback {
  name: string
  key: string
  success: (data?: string) => void
  fail: (data?: string) => void
}

@Entry
@Component
export struct MyWeb {
  webController: WebviewController = new webview.WebviewController()
  webUrl: string | Resource = "";

  build() {
    Column() {
      Web({ src: this.webUrl, controller: this.webController })
        .javaScriptProxy({
          object: {
            nativeMethod: (channelName: string, paramsCallback: IParamsCallback) => {
              if (!channelName || !paramsCallback) {
                return
              }
              switch (channelName) {
                case "openNativePage":
                  paramsCallback.success()
                  console.log("luvi > h5调用 openNativePage 方法,携带参数" + paramsCallback.name)
                  break;
                case "getCity":
                  paramsCallback.success()
                  console.log("luvi > h5调用 getCity 方法,携带参数" + paramsCallback.name)
                  break;
                default:
                  break;
              }
            },
          },
          name: 'JSBridge',
          methodList: ['nativeMethod'],
          controller: this.webController,
        })
        .fileAccess(true)
        .domStorageAccess(true)
        .zoomAccess(false)
        .width("100%")
        .height("100%")
    }
  }
}

案例效果

​编辑​

全部评论

相关推荐

上周组里招人,我面了六个候选人,回来跟同事吃饭的时候聊起一个让我挺感慨的现象。前三个候选人,算法题写得都不错。第一道二分查找,五分钟之内给出解法,边界条件也处理得干净。第二道动态规划,状态转移方程写对了,空间复杂度也优化了一版。我翻他们的简历,力扣刷题量都在300以上。后三个呢,就有点参差不齐了。有的边界条件没处理好,有的直接说这道题没刷过能不能换个思路讲讲。其中有一个女生,我印象特别深——她拿到题之后没有马上写,而是先问我:“面试官,我能先跟你确认一下我对题目的理解吗?”然后她把自己的思路讲了一遍,虽然最后代码写得不是最优解,但整个沟通过程非常顺畅。这个女生的代码不是最优的,但当我问她“如果这里是线上环境,你会怎么设计’的时候,她给我讲了一套完整的方案——异常怎么处理、日志怎么打、怎么平滑发布。她对这是之前在实习的时候踩过的坑。”我在想LeetCode到底在筛选什么?我自己的经历可能有点代表性。我当年校招的时候,也是刷了三百多道题才敢去面试。那时候大家都刷,你不刷就过不了笔试关。后来工作了,前三年基本没再打开过力扣。真正干活的时候,没人让你写反转链表,也没人让你手撕红黑树。更多的是:这个接口为什么慢了、那个服务为什么OOM了、线上数据对不上了得排查一下。所以后来我当面试官,慢慢调整了自己的评判标准。算法题我还会出,但目的变了。我出算法题,不是想看你能不能背出最优解。而是想看你拿到一个陌生问题的时候,是怎么思考的。你会先理清题意吗?你会主动问边界条件吗?你想不出来的时候会怎么办?你写出来的代码,变量命名乱不乱、结构清不清楚?这些才是工作中真正用得到的能力。LeetCode是一个工具,不是目的。它帮你熟悉数据结构和常见算法思路,这没问题。但如果你刷了三百道题,却说不清楚自己的项目解决了什么问题、遇到了什么困难、你是怎么解决的,那这三百道题可能真的白刷了。所以还要不要刷LeetCode?要刷,但别只刷题。刷题的时候,多问自己几个为什么:为什么用这个数据结构?为什么这个解法比那个好?如果换个条件,解法还成立吗?把刷题当成锻炼思维的方式,而不是背答案的任务。毕竟面试官想看到的,从来不是一台背题机器,而是一个能解决问题的人。
国企上岸了的向宇同桌...:最害怕答非所问了,但是频繁反问确定意思又害怕面试官觉得我笨
AI时代还有必要刷lee...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务