当前位置: 首页 > news >正文

HarmonyOS开发:传参方式

一、父子组件传参

1、父传子(@Prop方式)

父组件代码

@Entry
@Component
struct ParentComponent {@State parentMessage: string = 'Hello from Parent';build() {Column() {ChildComponent({ message: this.parentMessage });}}
}

子组件代码

@Component
struct ChildComponent {@Prop message: string;build() {Column() {Text(this.message);}}
}

2、父传子(@Link方式,实现双向绑定)

父组件代码

@Entry
@Component
struct ParentComponent {@State parentValue: number = 0;build() {Column() {ChildComponent({ value: $this.parentValue }); // 注意这里使用了$符号,表示传递的是引用Text('父组件的值: ' + this.parentValue);}}
}

子组件代码

@Component
struct ChildComponent {@Link value: number;build() {Column() {Text('子组件的值: ' + this.value);Button('Increase').onClick(() => {this.value += 1; // 修改子组件的值,父组件的值也会同步更新});}}
}

父组件ParentComponent通过@Link方式将parentValue的值传递给子组件ChildComponent,并实现了双向绑定。当子组件中的按钮被点击时,value的值会增加,同时父组件中的parentValue也会同步更新。

二、页面间的传参(使用router模板)

1、页面A代码

import { router } from '@ohos.router';@Entry
@Component
struct PageA {@State dataToSend: string = 'Data from Page A';build() {Column() {Button('Go to Page B').onClick(() => {router.pushUrl({url: 'pages/PageB',params: { message: this.dataToSend }});});}}
}

页面B代码

import { router } from '@ohos.router';@Entry
@Component
struct PageB {private receivedMessage: string = '';aboutToAppear() {const params = router.getParams();if (params && params.message) {this.receivedMessage = params.message;}}build() {Column() {Text('Received Message: ' + this.receivedMessage);}}
}

页面A通过router.pushUrl方法跳转到页面B,并在params参数中传递了dataToSend的值。页面B在aboutToAppear生命周期方法中通过router.getParams方法获取了这个值,并将其显示在页面上。

全局状态管理(使用装饰器)

// 定义全局状态管理器
@Observed
export class GlobalState {userLoggedIn: boolean = false;userName: string = "";
}// 组件A,用于修改全局状态
@Component
export struct ComponentA {@ObjectLink globalState: GlobalState;build() {Column() {Button("Login").onClick(() => {this.globalState.userLoggedIn = true;this.globalState.userName = "John Doe";});}}
}// 组件B,用于显示全局状态
@Component
export struct ComponentB {@Consume globalState: GlobalState;build() {Column() {if (this.globalState.userLoggedIn) {Text("User Logged In: " + this.globalState.userName);} else {Text("User Not Logged In");}}}
}

GlobalState 类被 @Observed 装饰器装饰,表示它是一个可观察的全局状态。ComponentA 和 ComponentB 分别使用 @ObjectLink 和 @Consume 装饰器来接收这个全局状态。当 ComponentA 修改全局状态时,ComponentB 会自动更新显示内容。

事件总线(Event Bus)

// 定义事件总线
const eventBus = new (function() {this.events = {};this.on = function(eventName, callback) {if (!this.events[eventName]) {this.events[eventName] = [];}this.events[eventName].push(callback);};this.emit = function(eventName, data) {if (this.events[eventName]) {this.events[eventName].forEach(function(callback) {callback(data);});}};
})();// 组件A,用于发送事件
@Component
export struct ComponentA {build() {Button("Send Event").onClick(() => {eventBus.emit("customEvent", { message: "Hello from ComponentA" });});}
}// 组件B,用于接收事件
@Component
export struct ComponentB {message: string = "";constructor() {eventBus.on("customEvent", (data) => {this.message = data.message;});}build() {Text(this.message);}
}

依赖注入(模拟)

// 数据服务组件的工厂类
class DataServiceFactory {static getDataService() {return new DataService();}
}// 数据服务组件
class DataService {getData() {return "Sample Data";}
}// 页面组件,使用依赖注入获取数据服务组件
@Component
export struct PageComponent {dataService: DataService;constructor() {this.dataService = DataServiceFactory.getDataService();}build() {Text(this.dataService.getData());}
}

创建了一个 DataServiceFactory 类来提供 DataService 的实例。在 PageComponent 中,我们通过调用 DataServiceFactory.getDataService() 方法来获取 DataService 的实例,并将其存储在 dataService 属性中。然后,我们在 build 方法中使用这个数据服务来获取数据并显示在页面上。

使用存储机制(用户首选项)

import dataPreferences from '@ohos.data.preferences';let context = getContext(this);
let preference: dataPreferences.Preferences;class PreferenceModel {async getPreferencesFromStorage(db_name: string) {try {preference = await dataPreferences.getPreferences(context, db_name);} catch (err) { }}async putData(key: string, data: string, db_name: string = "DB_NAME") {if (!preference) {await this.getPreferencesFromStorage(db_name);}try {await preference.put(key, data);} catch (err) { }await preference.flush();}async getData(key: string, db_name: string = "DB_NAME") {if (!preference) {await this.getPreferencesFromStorage(db_name);}return await preference.get(key, "");}
}const preferenceModel = new PreferenceModel();// 存储数据
preferenceModel.putData("name", "John Doe");// 读取数据
preferenceModel.getData("name").then((data) => {console.log("Name: " + data);
});

创建了一个 PreferenceModel 类来封装用户首选项的存储和读取操作。我们使用 getPreferencesFromStorage 方法来获取用户首选项的实例,并使用 putData 和 getData 方法来存储和读取数据。然后,我们使用这些方法来存储和读取名为 "name" 的数据。

通过服务进行通信(Service Ability)

// Service Ability 的实现
@Entry
@Service
export class MyService extends Ability {onConnect(intent: Intent): IRemoteObject {return new MyRemoteObject();}
}class MyRemoteObject extends RemoteObject implements IRemoteBroker {onRemoteRequest(code: number, data: MessageParcel, reply: MessageParcel, option: MessageOption): boolean {// 处理来自客户端的请求let message = data.readString();console.log("Received message from client: " + message);// 回复客户端reply.writeString("Hello from service!");return true;}
}// 客户端组件,用于连接和发送消息给 Service Ability
@Component
export struct ClientComponent {build() {Button("Send Message to Service").onClick(() => {let context = getContext() as UIAbilityContext;let intent = new Intent();intent.setElement(new ElementName("com.example.myapplication", "com.example.myapplication.MyService"));context.connectAbility(intent, (err, remoteObject) => {if (err) {console.error("Failed to connect to service: " + err.message);return;}let messageParcel = new MessageParcel();messageParcel.writeString("Hello from client!");remoteObject.sendRequest(1, messageParcel, (reply, option) => {let response = reply.readString();console.log("Received response from service: " + response);});});});}
}

创建了一个 MyService 类来定义 Service Ability。它实现了 onConnect 方法来返回一个 MyRemoteObject 实例,该实例用于处理来自客户端的请求。客户端组件 ClientComponent 使用 connectAbility 方法连接到 Service Ability,并使用 sendRequest 方法发送消息给服务。服务接收到消息后,处理消息并回复客户端。

使用第三方库或框架提供的传参机制案例

假设的第三方UI框架:HarmonyUI

1. 安装和配置第三方库

首先,确保你的项目已经配置了第三方UI框架 HarmonyUI。通常这需要在项目的 build.gradle 文件中添加依赖项。

dependencies {implementation 'com.example:harmonyui:1.0.0'
}

2. 创建两个组件:

SenderComponent 和 ReceiverComponent

SenderComponent.java
import com.example.harmonyui.Component;
import com.example.harmonyui.communication.DataSender;public class SenderComponent extends Component implements DataSender {private String dataToSend = "Hello, Receiver!";@Overrideprotected void onInit() {super.onInit();// 使用框架提供的API发送数据sendData("receiverId", dataToSend);}// HarmonyUI框架的DataSender接口实现@Overridepublic void sendData(String receiverId, String data) {// 调用框架提供的发送数据方法HarmonyUI.getInstance().sendData(receiverId, data);}
}
ReceiverComponent.java
import com.example.harmonyui.Component;
import com.example.harmonyui.communication.DataReceiver;public class ReceiverComponent extends Component implements DataReceiver {private String receivedData;@Overrideprotected void onInit() {super.onInit();// 注册接收数据的回调HarmonyUI.getInstance().registerDataReceiver(this, "receiverId");}@Overridepublic void onDataReceived(String data) {this.receivedData = data;// 更新UI或执行其他逻辑updateUI();}private void updateUI() {// 假设有一个显示数据的文本视图textView.setText(receivedData);}
}

3、在主应用中注册和使用这两个组件

MainApplication.java
import com.example.harmonyui.Application;
import com.example.harmonyui.layout.LinearLayout;public class MainApplication extends Application {@Overrideprotected void onCreate() {super.onCreate();// 创建布局LinearLayout layout = new LinearLayout();// 创建组件实例SenderComponent senderComponent = new SenderComponent();ReceiverComponent receiverComponent = new ReceiverComponent();// 将组件添加到布局中layout.addChild(senderComponent);layout.addChild(receiverComponent);// 设置主布局setMainLayout(layout);}
}

通过上述代码,SenderComponent 使用 HarmonyUI 框架提供的 sendData 方法将字符串数据发送给 ReceiverComponentReceiverComponent 通过实现 DataReceiver 接口并注册接收数据的回调来接收数据,并在接收到数据后更新UI。

码字不易,各位网友大佬点点赞呗

相关文章:

HarmonyOS开发:传参方式

一、父子组件传参 1、父传子(Prop方式) 父组件代码 Entry Component struct ParentComponent {State parentMessage: string Hello from Parent;build() {Column() {ChildComponent({ message: this.parentMessage });}} } 子组件代码 Component s…...

OpenCV计算机视觉 07 图像的模块匹配

在做目标检测、图像识别时,我们经常用到模板匹配,以确定模板在输入图像中的可能位置 API函数 cv2.matchTemplate(image, templ, method, resultNone, maskNone) 参数含义: image:待搜索图像 templ:模板图像 method&…...

国产游戏崛起,燕云十六移动端1.9上线,ToDesk云电脑先开玩

游戏爱好者的利好消息出新了!网易大型武侠仙游《燕云十六声》正式官宣,移动端要在1月9日正式上线了!你期待手游版的燕云吗?不妨评论区留言说说你的看法。小编分别花了几个小时在台式机电脑和手机上都试了下,欣赏画面还…...

企业级PHP异步RabbitMQ协程版客户端 2.0 正式发布

概述 workerman/rabbitmq 是一个异步RabbitMQ客户端,使用AMQP协议。 RabbitMQ是一个基于AMQP(高级消息队列协议)实现的开源消息组件,它主要用于在分布式系统中存储和转发消息。RabbitMQ由高性能、高可用以及高扩展性出名的Erlan…...

[OPEN SQL] 限定选择行数

本次操作使用的数据库表为SCUSTOM&#xff0c;其字段内容如下所示 航班用户(SCUSTOM) 该数据库表中的部分值如下所示 指定查询多少行数据&#xff0c;我们可以使用语法UP TO n ROWS来实现对数据前n项的查询 语法格式 SELECT * FROM <dbtab> UP TO n ROWS 参数说明 db…...

Vite源码学习分享(一)

!](https://i-blog.csdnimg.cn/direct/971c35b61c57402b95be91d2b4965d85.png) 同一个项目 vite VS webpack启动速度对比...

定位,用最通俗易懂的方法2:TDOA与对应的CRLB

二郎就不设置什么VIP可见啥的了&#xff0c;这样大家都能看到。 如果觉得受益&#xff0c;可以给予一些打赏&#xff0c;也算对原创的一些鼓励&#xff0c;谢谢。 钱的用途&#xff1a;1&#xff09;布施给他人&#xff1b;2&#xff09;二郎会有更多空闲时间写教程 起因&…...

Linux第一课:c语言 学习记录day06

四、数组 冒泡排序 两两比较&#xff0c;第 j 个和 j1 个比较 int a[5] {5, 4, 3, 2, 1}; 第一轮&#xff1a;i 0 n&#xff1a;n个数&#xff0c;比较 n-1-i 次 4 5 3 2 1 // 第一次比较 j 0 4 3 5 2 1 // 第二次比较 j 1 4 3 2 5 1 // 第三次比较 j 2 4 3 2 1 5 // …...

ExplaineR:集成K-means聚类算法的SHAP可解释性分析 | 可视化混淆矩阵、决策曲线、模型评估与各类SHAP图

集成K-means聚类算法的SHAP可解释性分析 加载数据集并训练机器学习模型 SHAP 分析以提取特征对预测的影响 通过混淆矩阵可视化模型性能 决策曲线分析 模型评估&#xff08;多指标和ROC曲线的目视检查&#xff09; 带注释阈值的 ROC 曲线 加载 SHAP 结果以进行下游分析 与…...

2025年第三届“华数杯”国际大学生数学建模竞赛A题题目

问题A&#xff1a;他能游得更快吗&#xff1f; 背景介绍 在2024年巴黎奥运会上&#xff0c;中国游泳运动员潘展乐凭借出色的表现成为全球瞩目的焦点。年仅19岁的他在男子100米自由泳比赛中以46秒40 的成绩夺冠&#xff0c;并创造了自己保持的世界纪录。在男子4100米混合泳接力…...

用c实现C++类(八股)

在 C 语言中&#xff0c;虽然没有内建的面向对象编程&#xff08;OOP&#xff09;特性&#xff08;如封装、继承、多态&#xff09;&#xff0c;但通过一些编程技巧&#xff0c;我们仍然可以模拟实现这些概念。下面将用通俗易懂的方式&#xff0c;逐步介绍如何在 C 中实现封装、…...

【C++多线程编程:六种锁】

目录 普通互斥锁&#xff1a; 轻量级锁 独占锁&#xff1a; std::lock_guard&#xff1a; std::unique_lock: 共享锁&#xff1a; 超时的互斥锁 递归锁 普通互斥锁&#xff1a; std::mutex确保任意时刻只有一个线程可以访问共享资源&#xff0c;在多线程中常用于保…...

【Javascript Day5】for循环及典型案例

for 循环 // 语法&#xff1a; for( 开始 ; 结束 ; 步长 ){ 循环体 } // for( var i 循环初始值 ; i的循环范围 ; i的增加或减少规则 ){ 循环体 } // 死循环 // for(;;){ // console.log("for循环"); // } // 循环打…...

#渗透测试#网络安全#一文了解什么是shell反弹!!!

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…...

《解锁图像的语言密码:Image Caption 开源神经网络项目全解析》

《解锁图像的语言密码&#xff1a;Image Caption 开源项目全解析》 一、开篇&#xff1a;AI 看图说话时代来临二、走进 Image Caption 开源世界三、核心技术拆解&#xff1a;AI 如何学会看图说话&#xff08;一&#xff09;深度学习双雄&#xff1a;CNN 与 RNN&#xff08;二&a…...

抢占欧洲电商高地,TikTok 运营专线成 “秘密武器”

在当今数字化浪潮席卷全球的时代&#xff0c;社交媒体平台已成为商业拓展的关键阵地&#xff0c;TikTok 更是其中的闪耀新星。近日&#xff0c;一则重磅消息引发行业关注&#xff1a;TikTok 正计划于 2025 年初进军荷兰电商市场。这一战略布局&#xff0c;不仅彰显了 TikTok 对…...

人工智能-数据分析及特征提取思路

1、概况 基于学生行为数据预测是否涉黄、涉黑等。 2.数据分析 数据分析的意义包括得到数据得直觉、发掘潜在的结构、提取重要的变量、删除异常值、检验潜在的假设和建立初步的模型。 2.1数据质量分析 2.1.1数据值分析 查看数据类型&#xff1a; 首先明确各字段的数据类型…...

2024 China Collegiate Programming Contest (CCPC) Zhengzhou Onsite 基础题题解

今天先发布基础题的题解&#xff0c;明天再发布铜牌题和银牌题的题解 L. Z-order Curve 思路&#xff1a;这题目说了&#xff0c;上面那一行&#xff0c;只有在偶数位才有可能存在1&#xff0c;那么一定存在这样的数&#xff0c;0 ,1,100, 10000,那么反之&#xff0c;我们的数…...

halcon3d 如何计算平面法向量!确实很简单

这个问题其实一直困扰了我很长时间,之前是怎么算的呢 对于一个平面,我会先求它的fit_primitives_object_model_3d去将它拟合,接下来用surface_normals_object_model_3d 算子生成它的法线,后用get_object_model_3d_params (ObjectModel3DNormals, ‘point_normal_x’, GenP…...

浅尝Appium自动化框架

浅尝Appium自动化框架 Appium自动化框架介绍Appium原理Appium使用安装平台驱动实战 坑 Appium自动化框架介绍 Appium 是一个开源的自动化测试框架&#xff0c;最初设计用于移动应用的测试&#xff0c;但现在它也扩展了对桌面端应用的支持。Appium 使得自动化测试变得更加简单&…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...