鸿蒙开发中V2状态管理的使用
鸿蒙状态管理V2版本在V1基础上进行了全面升级,新增了多种装饰器以优化状态观测能力。@Local取代@State确保状态内部初始化,@Param实现父子组件单向数据流,@Provider/@Consumer支持跨组件双向同步。针对复杂对象观测,引入@ObservedV2和@Trace组合装饰器。此外,AppStorageV2提供全局状态共享,PersistenceV2实现状态持久化,但需注意UI实
1、简介:
状态管理(V2)是鸿蒙开发中用于增强状态观测能力的新一代解决方案,相比V1版本在深度观测、性能优化和设计规范性方面有显著提升。
完整使用请参考官方文档:状态管理(V2)
本文最后将附上本案例的完整git代码,结合代码浏览博客效果更佳。
2、V2所属装饰器
(1)@Local
必须本地初始化,不允许外部传入初始化
@Local 的使用方法和V1版本的 @State 类似,但是由于 @State 装饰器既能本地初始化,又能够从外部初始化,无法确保 @State 装饰变量的初始值一定为组件内部定义的值,因此在V2版本中推出 @Local 装饰器表示组件的内部状态。
使用限制:
- @Local装饰器只能在 @ComponentV2 装饰的自定义组件中使用
- @Local 装饰的变量表示组件内部状态,不允许从外部传入初始化
@Local 与 @State 的用法、功能对比如下:
| @State | @Local | |
|---|---|---|
| 参数 | 无。 | 无。 |
| 从父组件初始化 | 可选。 | 不允许外部初始化。 |
| 观察能力 | 能观测变量本身以及一层的成员属性,无法深度观测。 | 能观测变量本身,深度观测依赖@Trace装饰器。 |
| 数据传递 | 可以作为数据源和子组件中状态变量同步。 | 可以作为数据源和子组件中状态变量同步。 |
(2)@Param
@Param 表示组件从外部传入的状态,使得父子组件之间的数据能够进行同步
★★★@Param 装饰的变量不允许在组件内部直接修改★★★
原因:@Param 的设计目的是实现父→子的单向数据流。若子组件直接修改 @Param 变量,会导致父子状态不一致(破坏单向性)。
@ComponentV2
export struct Example {
@Param address: string = '北京市'
build() {
Text("地址:" + this.address)
.onClick(() => {
// @Param 装饰的变量不允许在组件内部直接修改
// this.address = "深圳市" // 错误写法
})
}
}
(3)@Provider 和 @Consumer
@Provider 和 @Consumer 用于实现跨组件层级的双向数据同步,两者通过唯一的 aliasName 建立绑定关系,类似于V1装饰器中的 @Provide 和 @Consume。
@Provider,即数据提供方,其所有的子组件都可以通过 @Consumer 绑定相同的 key 来获取@Provider 提供的数据。
@Consumer,即数据消费方,可以通过绑定同样的 key 获取其最近父节点的 @Provider 的数据,当查找不到 @Provider 的数据时,使用本地默认值。
示例代码如下:
import { Example } from '../views/Example'
@Entry
@ComponentV2
struct Index {
@Provider('num') count: number = 0
build() {
Column({ space: 15 }) {
Button('父组件的值:' + this.count)
.width('100%')
.onClick(() => this.count++)
// 子组件
Example()
}
.padding(10)
.height('100%')
.width('100%')
}
}
@ComponentV2
export struct Example {
@Consumer('num') count: number = 0
build() {
Button("子组件的值:" + this.count)
.width('100%')
.onClick(() => this.count++)
}
}
效果如下:

(4)@ObservedV2 和 @Trace
@ObservedV2 和 @Trace 是V2所属装饰器中用于增强类对象属性观测能力的装饰器组合,主要解决嵌套类属性变化的直接观测问题。
@ObservedV2 装饰器与 @Trace 装饰器需要配合使用,未被 @Trace 装饰的属性用在UI中无法感知到变化。示例如下:
@ObservedV2
export class Person {
name: string = '张三'
@Trace age: number = 18
}
@ObservedV2
export class Profile {
@Trace person: Person = new Person()
}
@Entry
@ComponentV2
struct Index {
@Local personInfo: Profile = new Profile()
build() {
Column({ space: 15 }) {
Text(this.personInfo.person.name)
Text(this.personInfo.person.age + '')
.onClick(() => this.personInfo.person.age++)
}
.height('100%')
.width('100%')
}
}
3、其他状态管理
(1)AppStorageV2
AppStorageV2 是提供状态变量在应用级全局共享的能力,可以通过 connect 方法绑定同一个key,进行跨 ability 的数据共享。
使用限制:仅支持 class 类型
具体请参考官方文档:AppStorageV2
@ObservedV2
export class AreaHeight {
@Trace topHeight: number = 0
@Trace bottomHeight: number = 0
}
// 创建数据
const areaHeight = AppStorageV2.connect(AreaHeight, () => new AreaHeight()) as AreaHeight
areaHeight.topHeight = uiContext.px2vp(top.height)
areaHeight.bottomHeight = uiContext.px2vp(bottom.height)
@ComponentV2
export struct Example {
// 获取数据
areaHeight = AppStorageV2.connect(AreaHeight)!
build() {
Column() {
}
.padding({
top: this.areaHeight.topHeight,
bottom: this.areaHeight.bottomHeight
})
}
}
(2)PersistenceV2
PersistenceV2 提供状态变量持久化能力,需要注意的是,PersistenceV2 必须与 UI 实例关联,持久化操作需在 UI 实例初始化完成后调用(即 loadContent 回调触发后),而且不能持久化存储数组类型。
export class Keys {
value: string = "name_key"
}
PersistenceV2.connect(Keys, () => new Keys())
更多使用限制可参考官方文档:PersistenceV2 使用限制
本章完整示例代码可参考gitee地址:V2状态管理示例代码
更多推荐



所有评论(0)