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。

碼字不易,各位網友大佬點點贊唄

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/65377.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/65377.shtml
英文地址,請注明出處:http://en.pswp.cn/web/65377.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

deepin系統下開放指定端口

一、安裝ufw 若已安裝則跳過 sudo apt-get install ufw二、查看防火墻狀態 sudo ufw status三、打開防火墻 sudo ufw enable四、開放端口 sudo ufw allow 6654/tcp五、windows下測試遠程端口 telnet 192.168.1.22 6654六、關閉防火墻 sudo ufw disable附上ufw的全部命令…

微信小程序中使用 TypeScript 定義組件時,Component 函數確實需要多個類型參數

在微信小程序中使用 TypeScript 定義組件時,Component 函數確實需要多個類型參數,而不僅僅是一個。這些參數包括: Properties:組件的屬性(props)類型。 Data:組件的內部數據類型。 Methods&am…

我在廣州學 Mysql 系列——與索引相關的練習題

??大家好,我是練小杰,今天星期二啦,還有三天就是星期五了,為了美好生活奮斗吧朋友們! 本文將學習MYSQL中數據表內容的索引相關練習題目~~ 復習:👉【索引詳解】 數據庫專欄👉【數據…

通過 route 或 ip route 管理Linux主機路由

目錄 一:route 使用說明1、查看路由信息2、刪除指定路由3、增加指定路由 二:ip route 使用說明1、查看主機路由2、新增主機路由3、刪除主機路由 通過route 或者ip route修改Linux主機路由后屬于臨時生效,系統重啟后就恢復默認值了&#xff0c…

SASS 簡化代碼開發的基本方法

概要 本文以一個按鈕開發的實例,介紹如何使用SASS來簡化CSS代碼開發的。 代碼和實現 我們希望通過CSS開發下面的代碼樣式,從樣式來看,每個按鈕的基本樣式相同,就是顏色不同。 如果按照傳統的方式開發,需要開發btn &…

我用Ai學Android Jetpack Compose之Button

答案來自 通義千問,代碼同樣需要到Android Studio里實踐,才能學會。完整工程代碼見文末。 我要學Button,麻煩介紹一下 當然可以!Button 是 Jetpack Compose 中用于創建可點擊按鈕的 Composable 函數。它提供了豐富的配置選項來定…

flutter 專題三十六 Flutter動態化框架Thresh

一、前言 移動端技術棧自誕生以來,其雙端開發成本和發布效率一直廣受詬病。為了解決這些問題,前端跨端技術一直在不斷嘗試,希望能一次開發、多端運行并且能做到快速發布。期間經歷了多個技術發展階段。 第一階段:以H5為代表&…

NodeJs 箭頭函數:`()=>{}` 和 `()=>()` 的區別與使用場景

在 JavaScript 中,箭頭函數(Arrow Function)是一種簡潔的函數寫法,它不僅可以減少代碼量,還能避免 this 綁定的問題。然而,箭頭函數有兩種常見的寫法:()>{} 和 ()>()。這兩種寫法雖然看起…

緩存-Redis-緩存更新策略-主動更新策略-Cache Aside Pattern(全面 易理解)

**Cache-Aside Pattern(旁路緩存模式)**是一種廣泛應用于緩存管理的設計模式,尤其在使用 Redis 作為緩存層時尤為常見。該模式通過在應用程序與緩存之間引入一個旁路,確保數據的一致性和高效性。本文將在之前討論的 Redis 主動更新…

python制作翻譯軟件

本文復刻此教程:制作屬于自己的翻譯軟件-很簡單【Python】_嗶哩嗶哩_bilibili 一、明確需求(以搜狗翻譯為例) (1)網址:https://fanyi.sogou.com/text (2) 數據:翻譯內容…

【C++】20.二叉搜索樹

文章目錄 1. 二叉搜索樹的概念2. 二叉搜索樹的性能分析3. 二叉搜索樹的插入4. 二叉搜索樹的查找5. 二叉搜索樹的刪除6. 二叉搜索樹的實現代碼7. 二叉搜索樹key和key/value使用場景7.1 key搜索場景:7.2 key/value搜索場景:7.3 主要區別:7.4 ke…

vue3探索——使用ref與$parent實現父子組件間通信

在vue3中,可以使用vue3的API defineExpose()函數結合ref或者$parent,實現父子組件數據的傳遞。 子組件向父組件傳遞數據defineExpose()和ref 子組件:通過defineExpose() 函數,向外暴露響應式數據或者方法 // src/components/son…

Opencv圖片的旋轉和圖片的模板匹配

圖片的旋轉和圖片的模板匹配 目錄 圖片的旋轉和圖片的模板匹配1 圖片的旋轉1.1 numpy旋轉1.1.1 函數1.1.2 測試 1.2 opencv旋轉1.2.1 函數1.2.2 測試 2 圖片的模板匹配2.1 函數2.2 實際測試 1 圖片的旋轉 1.1 numpy旋轉 1.1.1 函數 np.rot90(kl,k1),k1逆時針旋轉9…

重溫設計模式--13、策略模式

策略模式介紹 文章目錄 策略模式介紹C 代碼示例 策略模式是一種行為設計模式,它允許在運行時選擇算法的行為。該模式將算法的定義和使用分離開來,使得算法可以獨立于使用它的客戶端而變化,提高了代碼的靈活性和可維護性。 其主要包含以下幾個…

計算機基礎知識復習1.5

標記-清除算法:標記-清除分為標記 和清除 兩個階段,首先通過可達性分析,標記出所有需要回收的對象,然后統一回收所有被標記的對象。 復制算法:為了解決碎片空間的問題,出現了復制算法 將內存分成兩塊&…

SQL Server 中的覆蓋索引

1. 覆蓋索引的工作原理 當查詢只涉及索引中已經包含的列時,SQL Server 可以直接使用索引來返回查詢結果,而不需要回表到數據頁去檢索實際的數據行。覆蓋索引因此能夠顯著減少 I/O 操作,提高查詢效率。 例如,假設有一個表 Employ…

Golang開發-案例整理匯總

前言 CSDN的文章缺少一個索引所有文章分類的地方,所以手動創建這么一個文章匯總的地方,方便查找。Golang開發經典案例匯總 GoangWeb開發 GolangWeb開發- net/http模塊 GolangWeb開發-好用的HTTP客戶端httplib(beego) GolangWeb開發- Gin不使用Nginx部署Vue項目 Golang并發開…

交叉編譯的核心原理與核心概念

什么是交叉編譯? 交叉編譯(Cross Compilation)是一種在一種計算機體系結構或操作系統(主機,Host)上生成另一種計算機體系結構或操作系統(目標,Target)上的可執行文件的過…

vue-codemirror定位光標位置并在光標處插入信息

業務場景:在代碼編輯器外點擊按鈕,向代碼編輯器內的光標處新增一條拼接好的信息。 getCursor方法: 官方文檔: doc.getCursor(?start: string) → {line, ch} Retrieve one end of the primary selection. start is an optional string indicating which end of the select…

【GOOD】A Survey of Deep Graph Learning under Distribution Shifts

深度圖學習在分布偏移下的綜述:從圖的分布外泛化到自適應 Northwestern University, USA Repository Abstract 圖上的分布變化——訓練和使用圖機器學習模型之間的數據分布差異——在現實世界中普遍存在,并且通常不可避免。這些變化可能會嚴重惡化模…