1、简介:

状态管理(V2)是鸿蒙开发中用于增强状态观测能力的新一代解决方案,相比V1版本在深度观测、性能优化和设计规范性方面有显著提升。

完整使用请参考官方文档:状态管理(V2)

本文最后将附上本案例的完整git代码,结合代码浏览博客效果更佳。


2、V2所属装饰器

(1)@Local

必须本地初始化,不允许外部传入初始化

@Local 的使用方法和V1版本的 @State 类似,但是由于 @State 装饰器既能本地初始化,又能够从外部初始化,无法确保 @State 装饰变量的初始值一定为组件内部定义的值,因此在V2版本中推出 @Local 装饰器表示组件的内部状态。

使用限制:

  1. @Local装饰器只能在 @ComponentV2 装饰的自定义组件中使用
  2. @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状态管理示例代码

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐