1.@State
- 用途: 用于管理组件内部的可变状态。当状态发生变化时,组件会重新渲染。
- 特点: 状态的变化只影响当前组件,并且在组件内部管理状态。
- 使用场景: 当你需要在组件内处理和更新状态时使用,比如按钮点击、输入框内容更新等。
@Entry
@Component
struct CounterComponent {
@State private count: number = 0;
build() {
Column() {
Text(`当前计数: ${this.count}`)
.fontSize(24)
Button("增加计数")
.onClick(() => {
this.count += 1; // 修改 @State 状态,触发组件重新渲染
})
}
}
}
2.@Prop
- 用途: 用于接收父组件传递的属性,@Prop 修饰的值是只读的,不能在子组件内部修改。
- 特点: 类似于其他框架中的 props,@Prop 数据从父组件传递,子组件只能读取,不能直接修改。
- 使用场景: 当你需要将数据从父组件传递给子组件时使用,数据通常不会在子组件内部修改。
@Component
struct ChildComponent {
@Prop private message: string;
build() {
Text(this.message)
.fontSize(18)
}
}
@Entry
@Component
struct ParentComponent {
build() {
Column() {
ChildComponent({ message: "来自父组件的消息" }) // 父组件向子组件传递数据
}
}
}
3.@Link
- 用途: 用于子组件引用父组件的状态。与 @Prop 不同,@Link 修饰的属性是双向绑定的,子组件可以改变该值。
- 特点: 双向绑定,子组件可以修改 @Link 修饰的值,父组件的状态也会随之更新。
- 使用场景: 当你需要在子组件中修改父组件的状态时使用。
@Component
struct ChildComponent {
@Link private count: number;
build() {
Column() {
Text(`子组件计数: ${this.count}`)
.fontSize(18)
Button("增加计数")
.onClick(() => {
this.count += 1; // 子组件修改 @Link 状态,父组件状态同步更新
})
}
}
}
@Entry
@Component
struct ParentComponent {
@State private count: number = 0;
build() {
Column() {
Text(`父组件计数: ${this.count}`)
.fontSize(24)
ChildComponent({ count: this.count }) // 传递状态给子组件
}
}
}
4.@Provide
- 用途: 用于提供状态或数据给其子组件,使得子组件可以共享和访问该数据,而不需要通过 @Prop 逐层传递。
- 特点: 数据或状态可以在层级较深的子组件中被访问到,方便管理全局共享数据。
- 使用场景: 当多个子组件需要共享父组件的数据时,避免层层传递 @Prop,可以使用 @Provide。
@Component
struct ParentComponent {
@Provide private theme: string = "light"; // 提供给子组件共享的数据
build() {
Column() {
Text("父组件")
ChildComponent() // 子组件无需通过 @Prop 获取
}
}
}
@Component
struct ChildComponent {
@Consume private theme!: string; // 消费父组件的提供数据
build() {
Text(`子组件主题: ${this.theme}`)
}
}
5.@Consume
- 用途: 与 @Provide 配合使用,用于子组件中获取由父组件通过 @Provide 提供的数据或状态。
- 特点: 子组件可以访问上层组件使用 @Provide 提供的数据。
- 使用场景: 当子组件需要从父组件或祖先组件获取共享数据时使用。
@Component
struct ParentComponent {
@Provide private theme: string = "dark"; // 父组件提供的状态
build() {
Column() {
Text("父组件")
ChildComponent() // 无需通过 @Prop 传递 theme
}
}
}
@Component
struct ChildComponent {
@Consume private theme!: string; // 子组件获取父组件提供的状态
build() {
Text(`子组件当前主题: ${this.theme}`)
}
}
6.@Observed
- 使用场景:
当你需要在多个组件之间共享复杂对象的状态,并希望这些状态的变化能自动反映在 UI 中时,可以使用 @Observed。
@Entry
@Component
struct ParentComponent {
@Observed private userInfo: User = new User("John", 25); // 声明一个可观察对象
build() {
Column() {
// 父组件展示 userInfo 数据
Text(`姓名: ${this.userInfo.name}`)
.fontSize(18)
Text(`年龄: ${this.userInfo.age}`)
.fontSize(18)
// 子组件传递 @Observed 对象
ChildComponent({ userInfo: this.userInfo })
}
}
}
class User {
constructor(public name: string, public age: number) {}
}
@Component
struct ChildComponent {
@Prop private userInfo!: User; // 子组件接收 @Observed 对象
build() {
Column() {
Text(`子组件中显示姓名: ${this.userInfo.name}`)
.fontSize(18)
// 修改 userInfo 对象的属性
Button("增加年龄")
.onClick(() => {
this.userInfo.age += 1; // 修改 @Observed 对象属性,父组件也会同步更新
})
}
}
}
7.@ObjectLink
- 使用场景:
当你需要让子组件直接修改父组件的复杂对象时使用,适合双向数据绑定。
@Entry
@Component
struct ParentComponent {
@State private user: User = new User("Alice", 30); // 父组件的对象状态
build() {
Column() {
// 父组件显示数据
Text(`姓名: ${this.user.name}`)
.fontSize(18)
Text(`年龄: ${this.user.age}`)
.fontSize(18)
// 子组件传递 @ObjectLink 对象
ChildComponent({ user: this.user })
}
}
}
class User {
constructor(public name: string, public age: number) {}
}
@Component
struct ChildComponent {
@ObjectLink private user!: User; // 双向绑定父组件的对象
build() {
Column() {
Text(`子组件显示姓名: ${this.user.name}`)
.fontSize(18)
// 修改父组件的 user 对象
Button("更改为 Bob")
.onClick(() => {
this.user.name = "Bob"; // 直接修改 user 对象,父组件的 UI 同步更新
})
Button("增加年龄")
.onClick(() => {
this.user.age += 1; // 直接修改 user 对象属性
})
}
}
}
总结
鸿蒙状态管理中的修饰符让组件间的状态传递和管理变得灵活。
@State 管理组件内部状态
@Prop 用于父组件传递数据,子组件不能修改
@Link 实现双向绑定,子组件可以修改
@Provide 与 @Consume 则提供了全局共享状态的机制。
@Observed:声明可观察对象,
@ObjectLink:用于实现双向数据绑定,允许子组件直接修改父组件的对象,适合复杂对象的双向传递。