HamronyOS开发5.0【数据】Web 组件

Web组件

HarmonyOS 提供了一个 Web 组件,我们可以借助它在我们的应用中内嵌一个浏览器,为开发者提供页面加载、页面交互、页面调试等能力,下图是官网给出的介绍。

1

该组件的使用场景和功能不多,但常用的一些功能需求还都有,这个还挺好玩的,挺方便的,例如我们有一个集中的固定 Web 用户反馈系统,我们的很多产品都使用该网页反馈系统来接收用户的反馈,那么在 APP 中我们就可以简单方便的直接嵌入该网页。

2

import web_webview from '@ohos.web.webview';
@Entry
@Component
struct WebPage {
  webviewController: web_webview.WebviewController = new web_webview.WebviewController();
  build() {
    Column() {
      Web({src:"https://juejin.cn/user/479835407267336",controller:this.webviewController})
        // 允许缩放
        .zoomAccess(true)
        // 文本缩放
        .textZoomAtio(150)
    }
  }
}

2

还可以进行本地 html 引入,想要执行页面中的 JavaScript 方法的话需要使用 runJavaScript 方法执行网页中的方法

import web_webview from '@ohos.web.webview';
@Entry
@Component
struct WebPage {
  webviewController: web_webview.WebviewController = new web_webview.WebviewController();
  build() {
    Column() {
      Button()
        .onClick(()=> {
          this.webviewController.runJavaScript("testFunc()");
        })
      Web({src: $rawfile('index.html'),controller:this.webviewController})
    }
  }
}

4

或者将我们在 arkts 中写的方法注入到 html 网页中去执行:[javaScriptProxy]

再或者我们可以建立一个双方的数据通信通道:[createWebMessagePorts]

Web 组件支持很多事件,这些事件可以让我们的应用和网页进行更好的交互

例如:onConfirm、onConsole、onDownloadStart、onErrorReceive等等等等

就 onConfirm 事件做出一个示例,主要是熟悉了解 HarmonyOS 中的各种开发场景

Web 组件支持 onConfirm 事件,当 html 网页中调用 confirm 告警方法的时候即会调用该方法,触发该回调,该回调又会接受一个event对象参数,包含了:

  • url:当前显示弹窗的网页地址
  • 弹窗中显示的信息
  • 通知 Web 组件用户操作行为

这个事件的作用也就是用户在网页上进行了一些操作,我们需要弹出一个告示框对用户进行一个提示,这时需要我们的应用和 html网页建立一个连接,建立一个数据通信的栈道,拿到数据之后可以在应用中做出相应的操作,下面的代码则是使用 AlertDialog 警告弹框组件将网页上的标题通过弹框展现了出来

import web_webview from '@ohos.web.webview';
@Entry
@Component
struct WebPage {
  webviewController: web_webview.WebviewController = new web_webview.WebviewController();
  build() {
    Column() {
      Button("点我触发事件")
        .onClick(()=> {
          this.webviewController.runJavaScript("testFunc()");
        })
      Web({src: $rawfile('index.html'),controller:this.webviewController})
        .onConfirm((event) => {
          console.log("event.url:" + event.url);
          console.log("event.message:" + event.message);
          console.log("event.result:" + event.result);
          AlertDialog.show({
            title: 'title',
            message: event.message
          })
          // 返回值为 true 的时候,可以调用系统的弹窗
          return true;
        })
    }
  }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<h2 class="text">Hello World!</h2>
</body>
<script>
    const testFunc = () => {
        console.log(document.querySelector(".text").textContent);
        confirm(document.querySelector(".text").textContent);
    }
</script>
</html>

5


数据请求

我们下面会实现这样一个页面功能效果:点击上方按钮,实现数据请求,然后将数据渲染至页面上

获取到数据之后我们再使用弹窗将数据展现出来玩一玩

6

  1. 定义一个数据类
export class MyData {
  id:number
  address:string
}
  1. 数据请求(非封装)

有兴趣的朋友可以抽取可变参数进行 全局 Request 的封装

import http from '@ohos.net.http';
import { MyData } from './MyData'

export default async function getHttpData(): Promise<MyData[]> {
    let dataList: MyData[] = []
    let httpRequest = http.createHttp();
    let response = httpRequest.request(
        "https://保密连接",
        {
            method: http.RequestMethod.GET,
            header: {
                'Content-Type': 'application/json'
            },
            expectDataType: http.HttpDataType.STRING, // 可选,指定返回数据的类型
        }
    );
    // 使用await和async,等待请求完成处理数据后返回
    await response.then((data) => {
        if (data.responseCode == 200) {
            // 处理返回结果
            const response = data.result + "";
            const res = JSON.parse(response).data
            for (let i = 0; i < res.length; i++) {
                let item = res[i];
                dataList.push({
                    address: item.address,
                    id:item.id
                });
            }
        } else {
        }
    }).catch((err) => {
        console.info('error:' + JSON.stringify(err));
    })
    return dataList;
}
  1. 拿到数据渲染页面
import getHttpData from './request';
import { MyData } from './MyData'
@Entry
@Component
struct WebPage {
  @State data:Array<MyData> = [];
  @State rangeList:Array<string> = [];
  @State select:number = 0;
  @State selectText:string = ""
  build() {
    Column() {
      Button("点击调用请求")
        .onClick(()=> {
          getHttpData().then((res=> {
            this.data = res;
            console.log(JSON.stringify(this.data));

            for (let i = 0; i < this.data.length; i++) {
              this.rangeList.push(this.data[i].address);
            }
          }))
        }
        )
      Row() {
        ForEach(this.data,(item:MyData)=> {
          Text(item.address)
            .fontSize(32)
            .fontColor("#ff197c70")
            .fontWeight(FontWeight.Bold)
        },item=> item.id)
      }
      .width("90%")
      .margin(32)
      .justifyContent(FlexAlign.SpaceBetween)

      Text(`您选择的城市为 :${this.selectText}`).margin(64)

      Button("选择你的所在地")
        .onClick(async ()=> {
          await TextPickerDialog.show({
            range:this.rangeList,
            selected:this.select,
            onAccept: (value: TextPickerResult) => {
              // 设置select为按下确定按钮时候的选中项index,这样当弹窗再次弹出时显示选中的是上一次确定的选项
              this.select = value.index;
              this.selectText = value.value;
              console.info("TextPickerDialog:onAccept()" + JSON.stringify(value));
            },
            onCancel: () => {
              console.info("TextPickerDialog:onCancel()");
            },
            onChange: (value: TextPickerResult) => {
              console.info("TextPickerDialog:onChange()" + JSON.stringify(value));
            }
          })
        })
    }
    .width("100%")
    .padding(32)
  }
}

数据管理-本地数据持久化

数据管理模块包括用户首选项、键值型数据管理、关系型数据管理、分布式数据对象和跨应用数据管理

而本地数据持久化分为三种:

  • 用户首选项(Preferences) :通常用于保存应用的配置信息。数据通过文本的形式保存在设备中,应用使用过程中会将文本中的数据全量加载到内存中,所以访问速度快、效率高,但不适合需要存储大量数据的场景。
  • 键值型数据库(KV-Store) :一种非关系型数据库,其数据以“键值”对的形式进行组织、索引和存储,其中“键”作为唯一标识符。适合很少数据关系和业务关系的业务数据存储,同时因其在分布式场景中降低了解决数据库版本兼容问题的复杂度,和数据同步过程中冲突解决的复杂度而被广泛使用。相比于关系型数据库,更容易做到跨设备跨版本兼容。
  • 关系型数据库(RelationalStore) :一种关系型数据库,以行和列的形式存储数据,广泛用于应用中的关系型数据的处理,包括一系列的增、删、改、查等接口,开发者也可以运行自己定义的SQL语句来满足复杂业务场景的需要。

用户首选项

7

8

它不保证遵循ACID(Atomicity, Consistency, Isolation and Durability)特性,数据之间无关系,进程中每个文件仅存在一个Preferences实例,应用获取到实例后,可以从中读取数据,或者将数据存入实例中。通过调用flush方法可以将实例中的数据回写到文件里

但是因为首选项是存储在内存中的,所以 Preferences 不适合存放过多的数据,这会使内存占用太多

应用首选项的持久化文件保存在应用沙箱内部,可以通过上下文获取其路径,官网为我们提供了一张它的运行机制

9

  • 保存数据(put)
  • 获取数据(get)
  • 是否包含指定的key(has)
  • 删除数据(delete)
  • 数据持久化(flush)

10

我们每次保存数据之后都要进行一次数据持久化操作来保证数据的存储,具体实现我们查看下面的代码:

  1. 分为两步,首先我们需要获取Preferences实例,然后再读取指定文件,将数据加载到Preferences实例,下面的代码算是做了一个小封装,但是封装的不够彻底,有需要朋友们可以进一步改进
import DataPreferences from '@ohos.data.preferences';
export class PreferencesUtils {
  public static getPreferences(context, name: string): Promise<DataPreferences.Preferences> {
    return new Promise<DataPreferences.Preferences>((resolved,rejected) => {
      DataPreferences.getPreferences(context, name)
        .then((res) => {
          resolved(res);
        })
        .catch(reason => {
          rejected(reason);
        })
    });
  }
}

上面这段代码的意思是导出了一个封装工具类,该工具类需要一个当前上下文,以及我们的”数据库“名称,准确来说是一个数据持久化文件名称,创建成功之后会返回一个 Promise 对象,解析为 DataPreferences.Preferences 类型的数据,供我们后续操作使用

  1. 页面实现 + 实例方法调用
import {PreferencesUtils} from '../common/preferencesUtil';
@Entry
@Component
struct Index {
  @State inputText:string = "";
  @State storeText:string = "";
  build() {
    Column({space:32}) {
      TextInput({placeholder:"请输入你的要存储的信息"})
        .placeholderColor("#54404040")
        .placeholderFont({weight:FontWeight.Bold})
        .enterKeyType(EnterKeyType.Done)
        .caretColor("#ff1dbf8c")
        .maxLength(50)
        .onChange((val)=> {
          this.inputText = val;
        }).margin(64)
      Text(`当前页面临时数据: ${ this.inputText }`)
        .fontWeight(FontWeight.Bold)
        .fontColor("#b9404040")

      Button("点击将临时数据本地持久化")
        .backgroundColor("#ff13887e")
        .fontWeight(500)
        .padding({top:12,left:24,bottom:12,right:24})
        .onClick(()=> {
          PreferencesUtils.getPreferences(globalThis.getContext(), 'data')
            .then((preferences) => {
              preferences.put('data', this.inputText).then((isPrivacy) => {
                AlertDialog.show(
                  {
                    title: '提示',
                    message: '数据存储成功',
                  }
                )
              })
            })
        })
      Button("点击获取持久化数据")
        .backgroundColor("#ff13887e")
        .fontWeight(500)
        .fontSize(18)
        .padding({top:24,left:42,bottom:24,right:42})
        .onClick(()=> {
          // PreferencesUtil.getContent("data");
          PreferencesUtils.getPreferences(globalThis.getContext(), 'data')
            .then((preferences) => {
              preferences.get('data', '默认数据', (err, val) => {
                if (!err) {
                  this.storeText = val.toString();
                }
                return;
              })
            })
        })
      Text(`已经本地数据持久化的数据:${this.storeText}`)
        .fontWeight(FontWeight.Bold)
        .fontColor("#b9404040")
    }
  }
}

剩下几个我就先晾着先不说了,有这一个也能大体满足我们的需求了,只是存储一些用户端数据,真用到大型或者用户相关数据也不需要这些本地存储了

第三方库的使用

我就单 axios 这个网络库来演示吧,因为原生 http 请求我还不是很习惯

12

对了,我在下包过程中遇到了一个问题,不过两秒就解决了,就是我们需要配置一下 ohpm 的环境变量,在 Path 中配置就行,文件路径是我们 Ohpm 的 bin 目录,在配置环境变量前跑一下 init.bat 文件初始化一下。

ohpm 安装路径忘了的话,可以去 DevEco Studio 的 设置中找到,如下图

13

回到正文,我们老规矩先配置网络权限

14

然后引入相关 api 进行网络请求:
15

代码如下:

import axios, { AxiosError, AxiosResponse } from '@ohos/axios';
axios<string, AxiosResponse<string>, null>({
  method: "get",
  url: 'https://mock.presstime.cn/mock/649419e43acfaff9262b52ef/example/mock'
}).then((res: AxiosResponse) => {
  console.info('result:' + JSON.stringify(res.data));
}).catch((error: AxiosError) => {
  console.error(error.message);
})

是不是一下子就简单了哈哈哈


最后呢,很多开发朋友不知道需要学习那些鸿蒙技术?鸿蒙开发岗位需要掌握那些核心技术点?为此鸿蒙的开发学习必须要系统性的进行。

而网上有关鸿蒙的开发资料非常的少,假如你想学好鸿蒙的应用开发与系统底层开发。你可以参考这份资料,少走很多弯路,节省没必要的麻烦。由两位前阿里高级研发工程师联合打造的《鸿蒙NEXT星河版OpenHarmony开发文档》里面内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(Harmony NEXT)技术知识点

如果你是一名Android、Java、前端等等开发人员,想要转入鸿蒙方向发展。可以直接领取这份资料辅助你的学习。下面是鸿蒙开发的学习路线图。

​​​​1

高清完整版请点击《鸿蒙NEXT星河版开发学习文档》

针对鸿蒙成长路线打造的鸿蒙学习文档。话不多说,我们直接看详细资料鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,帮助大家在技术的道路上更进一步。

《鸿蒙 (OpenHarmony)开发学习视频》

《鸿蒙生态应用开发V2.0白皮书》

《鸿蒙 (OpenHarmony)开发基础到实战手册》

《鸿蒙开发基础》

《鸿蒙开发进阶》

《鸿蒙开发实战》
在这里插入图片描述

获取这份鸿蒙星河版学习资料,请点击→《鸿蒙NEXT星河版开发学习文档》

总结

鸿蒙—作为国家主力推送的国产操作系统。部分的高校已经取消了安卓课程,从而开设鸿蒙课程;企业纷纷跟进启动了鸿蒙研发。

并且鸿蒙是完全具备无与伦比的机遇和潜力的;预计到年底将有 5,000 款的应用完成原生鸿蒙开发,未来将会支持 50 万款的应用。那么这么多的应用需要开发,也就意味着需要有更多的鸿蒙人才。鸿蒙开发工程师也将会迎来爆发式的增长,学习鸿蒙势在必行!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值