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!";

    @Override
    protected void onInit() {
        super.onInit();
        // 使用框架提供的API发送数据
        sendData("receiverId", dataToSend);
    }

    // HarmonyUI框架的DataSender接口实现
    @Override
    public 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;

    @Override
    protected void onInit() {
        super.onInit();
        // 注册接收数据的回调
        HarmonyUI.getInstance().registerDataReceiver(this, "receiverId");
    }

    @Override
    public 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 {
    @Override
    protected 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。

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【SpringBoot】日志处理-异常日志(Logback)

文章目录 异常日志(Logback)1、将 logback-spring.xml 文件放入项目的 src/main/resources 目录下2、配置 application.yml 文件3、使用 Logback 记录日志 异常日志(Logback) 使用 Logback 作为日志框架时,可以通过配…

【RK3568笔记】Android修改开机动画

概述 Android 的开机动画是由一系列连续的 PNG 图片作为帧组成的动画形式,不是一张 GIF 图片。将各帧 PNG 图片以压缩方式进行保存(压缩方式要求是存储压缩),并将保存的文件名命名为 bootanimation.zip,这个 bootanim…

复合机器人助力手机壳cnc加工向自动化升级

在当今竞争激烈的制造业领域,如何提高生产效率、降低成本、提升产品质量,成为众多企业面临的关键挑战。尤其是在手机壳 CNC 加工这一细分行业,随着市场需求的持续增长,对生产效能的要求愈发严苛。而复合机器人的出现,正…

HTML——75. 内联框架

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>内联框架</title><style type"text/css">iframe{width: 100%;height: 500px;}</style></head><body><!--iframe元素会创建包含…

(七)人工智能进阶之人脸识别:从刷脸支付到智能安防的奥秘,小白都可以入手的MTCNN+Arcface网络

零、开篇趣谈 还记得第一次用支付宝"刷脸"时的新奇感吗&#xff1f;或者被抖音的人脸特效逗乐的瞬间&#xff1f;这些有趣的应用背后&#xff0c;其实藏着一个精妙的AI世界。今天&#xff0c;就让我们开启一段奇妙的人脸识别技术探索之旅吧&#xff01; 一、人脸识…

1. 使用springboot做一个音乐播放器软件项目【前期规划】

背景&#xff1a; 现在大部分音乐软件都是要冲会员才可以无限常听的。对于喜欢听音乐的小伙伴&#xff0c;资金又比较紧张&#xff0c;是那么的不友好。作为程序员的我&#xff0c;也是喜欢听着歌&#xff0c;敲着代码。 最近就想做一个音乐播放器的软件&#xff0c;在内网中使…

STM32-笔记37-吸烟室管控系统项目

一、项目需求 1. 使用 mq-2 获取环境烟雾值&#xff0c;并显示在 LCD1602 上&#xff1b; 2. 按键修改阈值&#xff0c;并显示在 LCD1602 上&#xff1b; 3. 烟雾值超过阈值时&#xff0c;蜂鸣器长响&#xff0c;风扇打开&#xff1b;烟雾值小于阈值时&#xff0c;蜂鸣器不响…

【Linux】记录一下考RHCE的学习过程(七)

年底了&#xff0c;公司接的北京地铁轨道交通的项目做不完了&#xff0c;一百多列地铁的设备都得调&#xff0c;派我出差了几周&#xff0c;这几天才回来&#xff0c;出差累死了实在是没办法更新。&#xff08;YOASOBI的二开票还没抢到ToT&#xff0c;哭死&#xff0c;看看回滚…

[读书日志]从零开始学习Chisel 第六篇:Scala面向对象编程——特质(敏捷硬件开发语言Chisel与数字系统设计)

3.4特质 3.4.1什么是特质 特质使用trait开头&#xff0c;它与单例对象很像&#xff0c;两者都不能有输入参数&#xff0c;但单例对象是具体的&#xff0c;特质是抽象的。两者都不能用new实例化&#xff0c;类&#xff0c;单例对象&#xff0c;特质三者内部都可以包含字段和方…

VuePress2配置unocss的闭坑指南

文章目录 1. 安装依赖&#xff1a;准备魔法材料2. 检查依赖版本一定要一致&#xff1a;确保魔法配方准确无误3. 新建uno.config.js&#xff1a;编写咒语书4. 配置config.js和client.js&#xff1a;完成仪式 1. 安装依赖&#xff1a;准备魔法材料 在开始我们的前端魔法之前&…

游戏引擎学习第77天

仓库: https://gitee.com/mrxiao_com/2d_game 回顾昨天的 bug 今天我们继续开发进度&#xff0c;进行调试昨天代码的问题&#xff0c;主要是关于如何跟踪玩家和敌人在世界中的高度位置。虽然我们做的是一款 2D 游戏&#xff0c;但我们希望能够处理多层的房间&#xff0c;玩家…

uniapp结合movable-area与movable-view实现拖拽功能2

前言 上篇我们写了&#xff0c;固定高度的拖拽&#xff0c;这篇我们将进行不固定高度的拖拽模块编写完成。 开始 一、初始化 我们在list数组里面增加一个data的动态数组&#xff0c;这样可以动态改变元素的高度。 当前元素y 上一个元素的高度 <template><view s…

ubuntu为Docker配置代理

终端代理 我们平常在ubuntu终端中使用curl或git命令时&#xff0c;往往会很慢。 所以&#xff0c;首先需要给ubuntu终端环境添加代理。 查看自身那个软件的端口号&#xff0c;我这里是7890。 sudo gedit ~/.bashrcexport http_proxyhttp://localhost:7890 export https_pr…

【Uniapp-Vue3】v-if条件渲染及v-show的选择对比

如果我们想让元素根据响应式变量的值进行显示或隐藏可以使用v-if或v-show 一、v-show 另一种控制显示的方法就是使用v-show&#xff0c;使用方法和v-if一样&#xff0c;为true显示&#xff0c;为false则不显示。 二、v-if v-if除了可以像v-show一样单独使用外&#xff0c;还…

wujie无界微前端框架初使用

先说一下项目需求&#xff1a;将单独的四套系统的登录操作统一放在一个入口页面进行登录&#xff0c;所有系统都使用的是vue3&#xff0c;&#xff08;不要问我为啥会这样设计&#xff0c;产品说的客户要求&#xff09; 1.主系统下载wujie 我全套都是vue3&#xff0c;所以直接…

C语言 数组编程练习

1.将数组A的内容和数组B中的内容进行交换。&#xff08;数组一样大&#xff09; 2.创建一个整形数组&#xff0c;完成对数组的操作 实现函数Init()初始化数组全为0 实现print()打印数组的每个元素 实现reverse()函数完成数组元素的逆置 //2.创建一个整形数组&#xff0c;完…

【three.js】模型-几何体Geometry,材质Material

模型 在现实开发中&#xff0c;有时除了需要用代码创建模型之外&#xff0c;多数场景需要加载设计师提供的使用设计软件导出的模型。此时就需要使用模型加载器去加载模型&#xff0c;不同格式的模型需要引入对应的模型加载器&#xff0c;虽然加载器不同&#xff0c;但是使用方式…

MySQL和Hive中的行转列、列转行

水善利万物而不争&#xff0c;处众人之所恶&#xff0c;故几于道&#x1f4a6; 文章目录 MySQL1.行转列2.列转行 Hive1.行转列2.列转行(1)侧窗(2)union MySQL 1.行转列 把多行转成列。直接group&#xff0c;sum(if()) 2.列转行 Hive 1.行转列 select name,sum(if(kmshuxu…

unity学习8:unity的基础操作 和对应shortcut

目录 1 unity的基础操作的工具&#xff0c;就在scene边上 1.1 对应shortcut快捷键 2 物体的重置/ 坐标归到0附近 3 F&#xff1a;快速找到当前gameobject 4 Q&#xff1a;小手和眼睛&#xff0c;在场景中移动 5 W&#xff1a;十字箭头&#xff0c;移动gameobject 6 …

对话|全年HUD前装将超330万台,疆程技术瞄准人机交互“第一屏”

2024年&#xff0c;在高阶智驾进入快速上车的同时&#xff0c;座舱人机交互也在迎来新的增长点。Chat GPT、AR-HUD、车载投影等新配置都在带来新增量机会。 高工智能汽车研究院监测数据显示&#xff0c;2024年1-10月&#xff0c;中国市场&#xff08;不含进出口&#xff09;乘用…