Harmony(鸿蒙)数据变化通知
Harmony(鸿蒙)数据变化通知
关键字一
@State + @Prop(单向同步):
不管父组件数据变化,关联数据都会变化,而且子组件的@Prop可以继续使用@Prop链接,但是此方法只能局限于纯粹的祖父子页面传递,且层级之间需要添加关联变量
-
父组件通过 @State 管理数据,子组件通过 @Prop 接收数据;子组件修改数据不会反向同步父组件。
-
父组件向子组件传递只读数据。
// 父组件 @State message: string = "Hello"; Child({ message: this.message }) // 子组件 @Prop message: string; // 仅接收父数据
@State与@Link装饰器:
不管父子组件数据谁变化,关联数据都会变化,而且子组件的@Link可以继续使用@Link链接,但是此方法只能局限于纯粹的子父祖页面传递,且层级之间需要添加关联变量
-
@State: 组件内部的状态管理,状态变化会触发UI重新渲染。
-
@Link: 用于父子组件之间的双向数据绑定,需与父组件的@State或@Link变量关联。
@Entry @Component struct StateExample { @State count: number = 0 build() { Column() { Text(`Count: ${this.count}`).fontSize(30) Button('Increase').onClick(() => { this.count += 1 }) }.width('100%').height('100%').justifyContent(FlexAlign.Center) } } // 点击按钮时,count值变化,Text组件自动更新显示。 // @State变量仅对当前组件有效。 ``` - @Link用于建立父子组件间的双向绑定,需从父组件传递@State或@Link变量。 ```typescript // 子组件通过@Link接收父组件的@State变量(需用$符号传递引用)。 // 在子组件修改value会同步更新父组件的parentValue。 // 子组件 @Component struct ChildComponent { @Link value: number build() { Button(`Child Value: ${this.value}`) .onClick(() => { this.value += 1 // 修改会同步到父组件 }) } } // 父组件 @Entry @Component struct ParentComponent { @State parentValue: number = 0 build() { Column() { Text(`Parent Value: ${this.parentValue}`).fontSize(30) ChildComponent({ value: $parentValue }) // 使用$传递@State引用 }.width('100%').height('100%').justifyContent(FlexAlign.Center) } }
@Observed + @ObjectLink
-
@State 装饰器只能监听对象的直接属性替换或第一层属性变化,无法检测嵌套对象内部属性的修改
-
@Observed:装饰自定义类,标记其实例属性可被观察(需在类定义前使用)
-
@ObjectLink:在子组件中装饰变量,接收 @Observed 类的实例,建立双向数据绑定
@Observed 只能装饰类,不可单独用于变
@ObjectLink 变量不可直接赋值(如 this.user = new User() 非法),只能修改属性
嵌套对象属性同步
- 父组件通过 @State 管理 User 实例,子组件通过 @ObjectLink 绑定该实例
- 修改 user.age (无论父子组件)均触发界面更新
// 定义可观察类 @Observed class User { name: string; age: number; constructor(name: string, age: number) { this.name = name; this.age = age; } } // 父组件 @Entry @Component struct ParentPage { @State user: User = new User('Alice', 25); // 状态管理 build() { Column() { ChildComponent({ user: this.user }) // 传递对象 Button('修改年龄').onClick(() => { this.user.age++; // 父组件修改属性 }) } } } // 子组件 @Component struct ChildComponent { @ObjectLink user: User; // 双向绑定嵌套对象 build() { Column() { Text(`年龄: ${this.user.age}`) // 自动更新 Button('子组件修改').onClick(() => { this.user.age = 30; // 子组件修改同步到父组件 }) } } }
数组元素属性更新
-
每个数组元素 TodoItem 被 @Observed 装饰,子组件通过 @ObjectLink 监听其属性变化
-
切换开关时修改 item.completed 会同步更新 UI
@Observed class TodoItem { id: number; text: string; completed: boolean = false; constructor(id: number, text: string) { this.id = id; this.text = text; } } @Entry @Component struct TodoList { @State todos: TodoItem[] = [ new TodoItem(1, '买牛奶'), new TodoItem(2, '看书') ]; build() { Column() { ForEach(this.todos, (item: TodoItem) => { TodoItemComponent({ item: item }) // 传递数组项 }) } } } @Component struct TodoItemComponent { @ObjectLink item: TodoItem; // 绑定数组元素 build() { Row() { Text(this.item.text) .decoration({ type: this.item.completed ? TextDecorationType.LineThrough : TextDecorationType.None }) Toggle() .isOn(this.item.completed) .onChange((checked: boolean) => { this.item.completed = checked; // 修改元素属性 }) } } }
@Param 单向输入
-
父组件通过属性绑定传递数据,子组件用 @Param 接收,数据流为单向(父→子)
// 父组件 @ComponentV2 struct Parent { @Local message: string = "Hello"; build() { Child({ msg: this.message }) // 传递数据 } } // 子组件 @ComponentV2 struct Child { @Param msg: string = ""; // 接收父组件数据 }
@Provider + @Consumer
-
@Provider 提供数据,后代组件通过 @Consumer 绑定相同 key 实现双向同步
-
仅支持 ComponentV2,数据类型需严格匹配
// 父组件 @ComponentV2 struct Parent { @Provider('user') user: User = new User('Alice'); } // 子组件 @ComponentV2 struct Child { @Consumer('user') user: User; // 双向绑定 }
@Event 子传父通信
-
子组件通过 @Event 定义回调函数,父组件重写该函数实现数据回传
// 父组件 @ComponentV2 struct Parent { @Local title: string = "Title"; build() { Child({ onUpdate: (newTitle: string) => { this.title = newTitle; } }) } } // 子组件 @ComponentV2 struct Child { @Event onUpdate: (title: string) => void; Button("更新标题").onClick(() => this.onUpdate("New Title")); }
@ObservedV2 + @Trace
-
监听嵌套对象属性的深度变化,避免全对象刷新
@ObservedV2 class User { @Trace name: string; // 仅监听name变化 age: number; } @ComponentV2 struct Profile { @Local user: User = new User(); }
| 特性 | V1 (Component) | V2 (ComponentV2) |
|---|---|---|
| 双向同步 | @Provide + @Consume | @Provider + @Consumer |
| 事件回调 | 自定义事件 | @Event 装饰器 |
| 深度监听 | @Observed + @ObjectLink | @ObservedV2 + @Trace |
| 计算属性 | 无 | @Computed |
事件总线
EventHub
- 通过事件发布/订阅模式实现解耦通信
- 一对多广播、组件间松耦合交互
import eventHub from '@ohos.events.eventHub'; /*********************** 订阅事件 START *********************/ eventHub.on('customEvent', (data) => { console.log('Received event data:', data); }); // 异步处理 eventHub.on('asyncEvent', async (data) => { await someAsyncOperation(data); }); // 页面关闭时一定要:在组件销毁时及时取消订阅,防止内存泄漏。 eventHub.off('customEvent', callbackFunc); /********************** 订阅事件 END ************************/ /********************** 发布事件 START **********************/ // 发布普通事件 eventHub.emit('customEvent', { key: 'value' }); // 粘性事件 eventHub.emitSticky('stickyEvent', { stickyData: 'value' }); /********************** 发布事件 END ************************/
全局状态管理
AppStorage或LocalStorage
-
应用级全局存储,数据变化自动同步到所有依赖组件。
-
多组件共享的全局状态(如用户信息、主题)。
// 存储简单数据 AppStorage.SetOrCreate('theme', 'dark'); // 存储对象 AppStorage.SetOrCreate('user', { name: 'Alice', age: 25 }); // 直接读取 let theme = AppStorage.Get('theme'); // 在组件中响应式绑定 @Entry @Component struct MyComponent { @StorageLink('theme') theme: string = 'light'; build() { Text(`当前主题: ${this.theme}`) } } // 删除数据 AppStorage.Delete('theme'); // 对象类型监听 const user = AppStorage.SetAndLink('user', { name: 'Bob', age: 30 }); // 修改时会触发UI更新 user.age = 31;
观察者模式
当其他组件操作数据时,观察者能根据数据变化做出回应
createIntersectionObserver + observe + unobserve
// 导入API
import { IntersectionObserver } from '@ohos.intersectionobserver';
@Entry
@Component
struct VisibilityMonitor {
private observer: IntersectionObserver | null = null;
@State isVisible: boolean = false;
@State viewRatio: number = 0;
aboutToAppear() {
// 1. 创建观察者
this.observer = new IntersectionObserver();
// 2. 设置观察回调
this.observer.observe(this.$('targetView'), (isVisible: boolean, ratio: number) => {
this.isVisible = isVisible;
this.viewRatio = ratio;
console.log(`可见状态: ${isVisible}, 显示比例: ${ratio}`);
});
}
aboutToDisappear() {
// 3. 停止观察
this.observer?.unobserve(this.$('targetView'));
this.observer = null;
}
build() {
Column() {
// 被观察的目标组件
Text('Target View')
.width(200)
.height(200)
.backgroundColor(this.isVisible ? Color.Green : Color.Red)
.margin(20)
.id('targetView')
// 显示观察结果
Text(`可见: ${this.isVisible ? '是' : '否'}`)
Text(`显示比例: ${this.viewRatio.toFixed(2)}`)
}
}
}
@Component
struct ObserverExample {
private observer: IntersectionObserver | null = null;
aboutToAppear() {
// 创建并配置观察者
this.observer = this.createIntersectionObserver({
thresholds: [0.2, 0.5, 1.0],
observeAll: false
});
// 绑定观察回调
this.observer.observe('.scroll-view-item', (res) => {
console.log(`当前可见比例: ${res.intersectionRatio}`);
});
}
aboutToDisappear() {
// 组件销毁时解除观察
if (this.observer) {
this.observer.unobserve('.scroll-view-item');
this.observer = null;
}
}
build() {
Column() {
Scroll() {
ForEach([1, 2, 3, 4, 5], (item) => {
Text(`Item ${item}`)
.height(200)
.width('100%')
.backgroundColor(Color.Gray)
.class('scroll-view-item')
})
}
}
}
}
更多推荐

所有评论(0)