一、父子组件传参
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
方法将字符串数据发送给 ReceiverComponent
。ReceiverComponent
通过实现 DataReceiver
接口并注册接收数据的回调来接收数据,并在接收到数据后更新UI。
码字不易,各位网友大佬点点赞呗