HarmonyOS Web组件(二)

1. HarmonyOS Web组件

官方文档
在这里插入图片描述

1.1. 混合开发的背景和好处

  混合开发(Hybrid Development)是一种结合原生应用和Web应用的开发模式,旨在同时利用两者的优势。随着移动应用需求的多样化和复杂化,单一的开发方式往往难以满足所有需求。混合开发提供了一种灵活、高效的解决方案,特别是在以下方面具有显著的优势:
  (1)跨平台兼容:混合开发允许开发者编写一次代码,并在多个平台(如Android、iOS、HarmonyOS等)上运行。这大大减少了开发和维护成本。
  (2)快速迭代:Web技术(如HTML、CSS、JavaScript)的快速开发和部署能力,使得混合应用可以更快地进行迭代和更新。
  (3)丰富的Web生态:借助丰富的Web生态系统,开发者可以利用大量现有的Web库和框架,快速实现复杂功能。
  (4)原生性能:通过将关键功能部分使用原生代码实现,混合应用可以在保证性能的同时,享受Web开发的灵活性。

1.2.混合开发应用的结构

  为了更好地理解混合开发的概念,以下是一张示意图,展示了混合开发架构中原生代码与Web代码的结合。
在这里插入图片描述
  (图中展示了混合开发应用的结构,其中包括:
  (1)原生层 Native Layer:包括操作系统(如HarmonyOS)、设备硬件和原生API,提供高性能和底层功能支持。
  (2)Web层 Web Layer:包括HTML、CSS、JavaScript等Web技术,负责应用的界面和逻辑部分。
  (3)桥接层 Bridge Layer:连接原生层和Web层,允许两者之间的数据和功能交互。
  通过这种架构,开发者可以在Web层快速构建界面和业务逻辑,同时利用原生层提供的高性能和丰富功能,实现混合开发的最佳效果。
  在HarmonyOS NEXT Developer Beta1版本中,ArkTS 提供了强大的混合开发能力,允许开发者在应用中嵌入 Web 组件,利用 Web 技术构建应用的一部分。接下来,我将介绍如何在 ArkTS 中使用 Web 组件。

1.3. ArkTS Web 组件教程

1.3.1. 语法说明

  在 ArkTS 中,混合开发主要通过 Web 组件和 WebView API 来实现。通过这些工具,可以加载和显示网页内容,进行页面控制和数据交互。
  官方文档

1.3.1.1. 基本语法

  Web 组件用于在界面中嵌入一个网页浏览器。它的常用属性包括:
  src:指定要加载的网页资源地址。
  controller:webview控制器。

src: ResourceStr = 'https://m.jd.com'
Web({ src: this.src, controller: this.controller })

  注意:访问在线网页时需添加网络权限:ohos.permission.INTERNET

1.3.1.2 . 事件处理

  Web 组件支持多种事件,如:
(1)onPageBegin:页面开始加载时触发。
(2)onPageEnd:页面加载完成时触发。
(3)onErrorReceive:页面加载出错时触发。
(4)onTitleReceive:网页document标题更改时触发该回调。
(5)onProgressChange:网页加载进度变化时触发该回调。
(6)onRefreshAccessedHistory:加载网页页面完成时触发该回调,用于应用更新其访问的历史链接。
(7)onAppear:组件挂载显示后触发此回调(通用事件)。

      Web({ src: this.src, controller: this.controller }).onProgressChange((data) => {}).onPageBegin(() => {}).onPageEnd(() => {}).onErrorReceive((e) => {}).onTitleReceive((data) => {}).onRefreshAccessedHistory(() => {}).onAppear(() => {})
1.3.1.3 . WebView API

  WebView API 提供了一组方法和属性,用于更细粒度地控制 Web 组件,如加载URL、执行JavaScript代码等。

import { webview } from '@kit.ArkWeb'// 1. 创建 WebView 实例
controller = new webview.WebviewController()
// 2. 调用WebView 实例 api 进行控制
run() {// 动态加载页面this.controller.loadUrl('url')// 注入 js 对象this.controller.registerJavaScriptProxy// ...
}
Web({ src: this.src, controller: this.controller })

1.3. 实战案例

1.3.1. 新建工程

主要目录结构:

|-- entry
|   |-- src
|   |   |-- main
|   |   |   |-- ets
|   |   |   |   |-- pages
|   |   |   |   |   |-- Index.ets(案例代码)
|-- module.json5

1.3.2. 配置权限

在 module.json5 中配置网络权限:

{"module": {"name": "entry","type": "entry","description": "$string:module_desc",// ..."requestPermissions": [{ "name": "ohos.permission.INTERNET" }],"deliveryWithInstall": true,"installationFree": false,"pages": "$profile:main_pages","abilities": [// ...],"extensionAbilities": [// ...]}
}

1.3.3. 加载页面

在 Index.ets 文件中,使用 Web 组件和 WebView API,加载web页面:

@Entry
@Component
struct WebPage {// 1. web 组件基本使用src: ResourceStr = 'https://m.jd.com'// webview控制器controller = new webview.WebviewController()build() {Navigation() {Web({ src: this.src, controller: this.controller })}.title('混合开发').titleMode(NavigationTitleMode.Mini)}
}

1.3.4. 页面标题

获取当前加载网页标题,进行动态展示

  // ...@State// 当前网页的标题title: string = ''build() {Navigation() {Web({ src: this.src, controller: this.controller }).onTitleReceive((data) => {this.title = data?.title || '--'})}.title(this.title).titleMode(NavigationTitleMode.Mini)}

1.3.5. 页面进度

获取页面进度数据,添加进度条效果:
(1)第一步:定义状态,存储加载中和进度数据

  // 当前访问页面历史记录索引historyCurrIndex: number = 0

(2)第二步:添加事件获取历史记录

// ...
.onRefreshAccessedHistory(() => {
// == 网页加载完成可访问页面历史记录 ==
// 获取当前Webview的页面历史记录列表
const history = this.controller.getBackForwardEntries()
// 当前页面历史记录索引
this.historyCurrIndex = history.currentIndex
// 历史记录索引的数量,最多保存50条,超过时起始记录会被覆盖
console.log('mgx', history.size)
})

(3)第三步:在原生返回钩子函数中控制逻辑

  onBackPress() {// 在web容器中, 当前页面之前还有页面, 则容器内返回上一页if (this.historyCurrIndex > 0) {this.controller.backward()} else {// 返回原生页面router.back()}// 自定义返回逻辑return true}

1.3.6. 在页面标题中添加菜单图标,点击刷新页面。

(1)第一步:给Navigation组件右侧添加菜单(图标随便)

build() {Navigation() {// ...}
.title(this.title)
.titleMode(NavigationTitleMode.Mini)
.menus(this.titleMenus)
}

(2)第二步:定义菜单 Builder 绑定事件控制刷新

  @BuildertitleMenus() {Row() {Image($r('app.media.startIcon')).width(18).aspectRatio(1).margin({ right: 10 }).onClick(() => {// 刷新网页this.controller.refresh()})}.width(50).height('100%').justifyContent(FlexAlign.End).alignItems(VerticalAlign.Center)}

1.3.7. JSBridge代理

  接下来,进入重点环节,我们来学习实操下如何向 Web 容器的网页中注入 JS 对象,给网页提供原生的能力支持,例如: 选择相册、拍照、传感器等底层能力。
  核心依赖webview 提供的registerJavaScriptProxy api,提供了应用与Web组件加载的网页之间强大的交互能力。注入JavaScript对象到window对象中,并在window对象中调用该对象的方法。

官方参考文档
(1)第一步:定义注入 JS 的类型
  示例注入了两个函数:
  test 方法,获取网页调用后传参
  select 方法,选择原生相册,获取选择图片结果显示到网页中

interface InjectJs {// 测试方法test: (a: string) => void// 选择相册select: () => Promise<string>
}type InjectKeys = keyof InjectJs

(2)第二步:定义注入的方法和逻辑

  // 2. JSBridge代理webInject() {this.controller.registerJavaScriptProxy({// 参数 1:注入应用侧JavaScript对象// 参数 2:注入对象的名称,与window中调用的对象名一致// 参数 3:注入后window对象可以通过此名字访问应用侧JavaScript对象test: (a) => {AlertDialog.show({message: `网页传参:${a}`})},select: async () => {// 1. 打开相册选择图片const photoSelectOptions = new picker.PhotoSelectOptions()photoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE;photoSelectOptions.maxSelectNumber = 1;const photoPicker = new picker.PhotoViewPicker();const res = await photoPicker.select(photoSelectOptions)// 2. 文件操作// 2.1 获取照片的uri地址const uri = res.photoUris[0]// 2.2 根据uri同步打开文件const file = fs.openSync(uri)// 2.3 同步获取文件的详细信息const stat = fs.statSync(file.fd)// 2.4 创建缓冲区存储读取的文件流const buffer = new ArrayBuffer(stat.size)// 2.5 开始同步读取文件流到缓冲区fs.readSync(file.fd, buffer)// 2.6 关闭文件流fs.closeSync(file)// 3. 转成base64编码的字符串const helper = new util.Base64Helper()const str = helper.encodeToStringSync(new Uint8Array(buffer))return 'data:image/png;base64,' + str}} as InjectJs,'mg',['test','select',] as InjectKeys[])}

(3)第三步:在通用事件onAppear 执行注入

Web({ src: this.src, controller: this.controller })
// ...
.onAppear(() => {
// JSBridge代理注入
this.webInject()
})

(4)第四步:本地创建网页加载
  这里使用的是原生 js 开发网页端,实际开发中可选择 vue 、 react 、 uni-app 等框架开发,效率更高。
  目录:entry/src/main/resources/rawfile/index.html

<!doctype html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>混合开发</title><style>* {margin: 0;padding: 0;}ul li {padding: 10px;}
</style>
</head><body>
<div><h1>H5页面</h1><div><p><!--     显示选择相册的图片       --><img id="img"src=""></p></div><ul><li><button id="test">调用原生test</button></li><li><button id="sel">调用原生select选择相册</button></li></ul>
</div>
<script>window.onload = () => {document.querySelector('#test').addEventListener('click', () => {mg.test('我是来自web数据啦')})document.querySelector('#sel').addEventListener('click', async () => {const b64 = await mg.select()document.querySelector('#img').setAttribute('src', b64)})}
</script>
</body></html>

1.3.8. 执行网页JS

  有时候,我们需要在原生端调用网页中 JS,完成一些业务需求。
(1)第一步:网页中挂载 JS到 window
重新运行项目,点击按钮调用注入的函数测试

<script>window.go = () => {return '我是网页JS函数'}window.onload = () => {// ...}
</script>

(2)原生端调用挂载的 JS
借助 webview 提供runJavaScript api 异步执行JavaScript脚本,并通过回调方式返回脚本执行的结果。

官方参考文档

  // 3. 执行网页 jsrunJs() {// this.controller.loadUrl($rawfile('index.html'))this.controller.runJavaScript('go()', (error, res) => {if (error) {return AlertDialog.show({message: error.message})}// 获取执行返回值AlertDialog.show({message: res})})}build() {Navigation() {Button('执行网页 js').onClick(() => {this.runJs()})// ...}
}

1.4. 总结

  本文介绍了在 HarmonyOS NEXT Developer Beta1 版本中,使用 ArkTS 进行混合开发时 Web 组件的基本用法。通过 Web 组件和 WebView API,可以轻松地在应用中嵌入和控制网页内容。以下是几个关键点的总结:
(1)基本语法:通过 Web 组件可以加载和显示网页,处理页面事件,并与网页进行交互。
(2)事件处理:支持多种事件处理,如页面开始加载、加载完成和加载出错、访问历史记录等。
(3)API 使用:WebView API 提供了丰富的方法,用于充当 Bridge 代理,更好和网页端进行通信。
  通过本文的介绍,你应该能够初步掌握在 ArkTS 中使用 Web 组件的基本方法,并应用于实际开发中。混合开发可以让你充分利用 Web 技术的优势,同时享受 ArkTS 的高效开发体验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/48433.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

sass版本更新,不推荐使用嵌套规则后的声明

目前在 Sass 中不推荐使用嵌套规则后的声明&#xff0c;在 为了通知用户即将进行的更改&#xff0c;并给他们时间进行更改 与之兼容的样式表。在未来的版本中&#xff0c;Dart Sass 将更改为 匹配纯 CSS 嵌套生成的顺序。Deprecation Warning: Sasss behavior for declarations…

Pytorch学习笔记【B站:小土堆】

文章目录 1 基础环境配置&#xff08;CPU版&#xff09;2 PyTorch学习2.1 Dataset和DataLoader2.1.1 Dataset2.1.2 DataLoader 2.2 Tensorboardadd_scalaradd_imageadd_graph 2.3 Transforms2.3.1 ToTensor2.3.2 Normalize2.3.3 Resize2.3.4 Compose 2.4 torchvision中的数据集…

pnpm build打包时占内溢出

这两天在打包H5网页的时候失败&#xff0c;总是提示下方错误 FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory 严重错误&#xff1a;堆限制附近标记压缩无效分配失败 - JavaScript 堆内存不足 尝试了多种方法&…

Linux源码安装的Redis如何配置systemd管理并设置开机启动

文章目录 实验前提实验 实验前提 已完成源码安装并能正常启动redis /usr/local/bin/redis-server能正常启动redis 实验 vim /etc/systemd/system/redis.service内容如下&#xff1a; [unit] Descriptionredis-server Afternetwork.target[Service] Typeforking ExecStart/…

【Blockly图形化积木编程二次开发学习笔记】5.自动保存与恢复

文章目录 引用使用 引用 <script src"./blockly/appengine/storage.js"></script>使用 <script>window.setTimeout(BlocklyStorage.restoreBlocks, 0); // 从本地存储中恢复块BlocklyStorage.backupOnUnload(); // 用户离开页面时自动将块备份到…

降雨量预测 | Matlab基于ARIMA-RBF降雨量预测

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 降雨量预测 | Matlab基于ARIMA-RBF降雨量预测 注&#xff1a;程序和数据放在一个文件夹。 程序语言为matlab&#xff0c;程序可出预测效果图&#xff0c;指标图; 代码特点&#xff1a;参数化编程、参数可方便更改、代…

web前端学习笔记Day02

web学习Day02 一、页面布局 盒子模型 盒子将页面的所有标签都包含在了一个矩形区域content(内容区域)->padding(内边距区域)->border(边框区域)->margin(外边距区域) div标签: 一行只能显示一个&#xff08;独占一行&#xff09;width默认为父元素宽度&#xff0c…

Docker核心技术:Docker原理之Namespace

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是 Docker核心技术 系列文章&#xff1a;Docker原理之Namespace&#xff0c;其他文章快捷链接如下&#xff1a; 应用架构演进容器技术要解决哪些问题Docker的基本使用Docker是如何实现的 Docker核心技术&#xff1…

多模态AI:概念、用例、优势、挑战及发展未来

多模态实际上是在尝试复制人类的感知方式&#xff1a;我们将视觉、声音和触觉等感官输入结合起来&#xff0c;形成对现实的更细致入微的感知&#xff0c;并利用这些数据来做出决定或采取行动。多模态模式也在尝试做同样的事情。 多模态AI的应用范围正在不断扩大&#xff0c;那么…

使用 useLazyAsyncData 提升数据加载体验

title: 使用 useLazyAsyncData 提升数据加载体验 date: 2024/7/19 updated: 2024/7/19 author: cmdragon excerpt: 摘要&#xff1a;本文介绍useLazyAsyncData函数在Nuxt 3中的使用&#xff0c;以提升数据加载体验。此函数支持异步获取数据并在组件中处理挂起与错误状态&…

IOCTLance:一款针对x64 WDM驱动程序的漏洞检测工具

关于IOCTLance IOCTLance是一款针对x64 WDM驱动程序的漏洞检测工具&#xff0c;该工具来源于CODE BLUE 2023上展示的一个名为“使用符号执行和污点分析增强 WDM 驱动程序漏洞检测 ”的项目。该工具能够有效增强检测Windows驱动程序模型&#xff08;WDM&#xff09;驱动程序中各…

Redis之List列表

目录 一.列表讲解 二.列表命令 三.内部编码 四.应用场景 Redis的学习专栏&#xff1a;http://t.csdnimg.cn/a8cvV 一.列表讲解 列表类型是用来存储多个有序的字符串&#xff0c;如下所示&#xff0c;a、b、c、d、e五个元素从左到右组成了一个有序的列表&#xff0c;列表中的…

微软史诗级的蓝屏

本周经历了微软的蓝屏&#xff0c;一直到周末还在加班处理公司的问题。 个人终端受到的影响较大&#xff0c;服务器上也受到了影响。因为蓝屏的事情导致不少麻烦&#xff0c;据同事说因为蓝屏的问题&#xff0c;MGH 的手术安排也受到了影响。 目前我们也在着手处理有部署 Wind…

基于SpringBoot+Vue的网吧管理系统(带1w+文档)

基于SpringBootVue的网吧管理系统(带1w文档) 基于SpringBootVue的网吧管理系统(带1w文档) 网吧管理系统&#xff0c;为了随时随地查看网吧管理信息提供了便捷的方法&#xff0c;更重要的是大大的简化了管理员管理网吧的方式方法&#xff0c;更提供了其他想要了解网吧管理信息及…

【云原生】Prometheus 服务自动发现使用详解

目录 一、前言 二、Prometheus常规服务监控使用现状​​​​​​​ 2.1 Prometheus监控架构图 2.2 Prometheus服务自动发现的解决方案 三、Prometheus服务自动发现介绍 3.1 什么是Prometheus服务自动发现 3.2 Prometheus自动服务发现策略 3.3 Prometheus自动服务发现应用…

SQL39道常见题型

SQL1 查询所有列 现在运营想要查看用户信息表中所有的数据&#xff0c;请你取出相应结果。 select * from user_profile 结果&#xff1a; SQL2 查询多列 还是上面那个输入&#xff0c;题目换成&#xff1a;现在运营同学想要用户的设备id对应的性别、年龄和学校的数据&#…

Springboot同时支持http和https访问

springboot默认是http的 一、支持https访问 需要生成证书&#xff0c;并配置到项目中。 1、证书 如果公司提供&#xff0c;则直接使用公司提供的证书&#xff1b; 如果公司没有提供&#xff0c;也可自己使用Java自带的命令keytool来生成&#xff1a; &#xff08;1&#x…

Flink History Server配置

目录 问题复现 History Server配置 HADOOP_CLASSPATH配置 History Server配置 问题修复 启动flink集群 启动Histroty Server 问题复现 在bigdata111上执行如下命令开启socket&#xff1a; nc -lk 9999 如图&#xff1a; 在bigdata111上执行如下命令运行flink应用程序 …

手动构建线性回归(PyTorch)

import torch from sklearn.datasets import make_regression import matplotlib.pyplot as plt import random #1.构建数据 #构建数据集 def create_dataset():x,y,coefmake_regression(n_samples100,n_features1,random_state0,noise10,coefTrue,bias14.5)#将构建数据转换为张…

Linux系统命令:监控 CPU 性能的工具mpstat详解

目录 一、概述 二、语法和使用 1、基本语法 2、常用选项 三、安装 mpstat 1、Debian&#xff08;如 Ubuntu&#xff09;的系统安装 2、CentOS 或 Fedora系统的安装 &#xff08;1&#xff09;安装指令 &#xff08;2&#xff09;安装操作 3、使用 四、示例 1. 查看…