【鸿蒙实战开发】基于状态变量实现复杂对象的状态监听

场景一:简单对象监听

对象在我们开发过程中是很常见的数据类型,我们在进行UI渲染的时候经常会用到对象,这里提供简单对象(所有字段均为基本数据类型)的监听效果。

方案一:状态管理V1实现

简单对象可以直接使用@State观测,这里使用起来比较简单,但是需要注意的是如果某个Class在页面中渲染中使用的字段较多的时候,可以结合@Track修饰器来进行观测。

实现代码:

@Builder 
export function SimpleObjectBuilder(name: string, param: Object) { 
  SimpleObject() 
} 

class LogTrack { 
  // 这里使用@Track可以达到最小化更新的效果 
  @Track str1: string; 
  @Track str2: string; 

  constructor(str1: string) { 
    this.str1 = str1; 
    this.str2 = 'World'; 
  } 
} 

class LogNotTrack { 
  str1: string; 
  str2: string; 

  constructor(str1: string) { 
    this.str1 = str1; 
    this.str2 = '世界'; 
  } 
} 

@Component 
export struct SimpleObject { 
  pathStack: NavPathStack = new NavPathStack() 
  @State logTrack: LogTrack = new LogTrack('Hello'); 
  @State logNotTrack: LogNotTrack = new LogNotTrack('你好'); 

  isRender(index: number) { 
    console.log(`Text ${index} is rendered`); 
    return 50; 
  } 

  build() { 
    NavDestination() { 
      Column() { 
        Column() { 
          Text(this.logTrack.str1)// UINode1 
            .fontSize(this.isRender(1)) 
            .fontWeight(FontWeight.Bold) 
          Text(this.logTrack.str2)// UINode2 
            .fontSize(this.isRender(2)) 
            .fontWeight(FontWeight.Bold) 
          Button('change logTrack.str1') 
            .onClick(() => { 
              // 点击更新str1 字段,观察页面日志变化,会发现使用@Track修饰的变量只会对改变的变量做最小化更新 
              this.logTrack.str1 = 'Bye'; 
            }) 
          Text(this.logNotTrack.str1)// UINode3 
            .fontSize(this.isRender(3)) 
            .fontWeight(FontWeight.Bold) 
          Text(this.logNotTrack.str2)// UINode4 
            .fontSize(this.isRender(4)) 
            .fontWeight(FontWeight.Bold) 
          Button('change logNotTrack.str1') 
            .onClick(() => { 
              // 点击更新str1字段,观察页面日志变化,会发现在不使用@Track修饰即使只改变了一个值,但是对象中所有的字段全都会触发UI更新那么值没有发生改变 
              this.logNotTrack.str1 = '再见'; 
            }) 
        } 
      }.width('100%').height('100%') 
    }.onReady((context: NavDestinationContext) => { 
      this.pathStack = context.pathStack; 
    }) 
  } 
}

实现效果如下:

image.png

观察日志发现第一种在更新UI的时候只会对操作的UI进行重绘渲染,而第二种在更新UI的时候所有在页面中用到了的组件都会进行重绘,所以为了解释性能,我们更建议在Class中使用@Track对字段进行精准修饰。

方案二:状态管理V2实现

在状态管理V2中对于对象的观察只有一套框架@ObservedV2+@Trace,它们具备深度观测对象的能力,简单对象也同样可以观测。

需要注意的是使用@ObservedV2修饰的类,如果字段需要观测变化的时候需要对该字段使用@Trace进行修饰,否则UI不会刷新。

实现代码:

@Builder 
export function SimpleObjectBuilderV2(name: string, param: Object) { 
  SimpleObject() 
} 

@ObservedV2 
class LogTrack { 
  @Trace str1: string; 
  str2: string; 

  constructor(str1: string) { 
    this.str1 = str1; 
    this.str2 = 'World'; 
  } 
} 

@ComponentV2 
struct SimpleObject { 
  pathStack: NavPathStack = new NavPathStack() 
  logTrack: LogTrack = new LogTrack('hello'); 

  isRender(index: number) { 
    console.log(`Text ${index} is rendered`); 
    return 50; 
  } 

  build() { 
    NavDestination() { 
      Column() { 
        Text(this.logTrack.str1)// UINode1 
          .fontSize(this.isRender(1)) 
          .fontWeight(FontWeight.Bold) 
        Text(this.logTrack.str2)// UINode2 
          .fontSize(this.isRender(2)) 
          .fontWeight(FontWeight.Bold) 
        Button('change logTrack.str1') 
          .onClick(() => { 
            // 点击更新Str1和str2,str1使用了@Trace修饰,UI界面正常刷新,Str2没有修饰,UI界面不刷新 
            this.logTrack.str1 = 'Hi'; 
            this.logTrack.str2 = '世界'; 
          }) 
      } 
    }.onReady((context: NavDestinationContext) => { 
      this.pathStack = context.pathStack; 
    }) 
  } 
}

image.png

并且使用@Trace修饰的字段也具备最小化更新的能力,具体见下方日志:
image.png

另外还需要注意的是,被&

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值