状态管理@State

news/2024/7/21 8:51:28 标签: harmonyos

       

目录

一、简单类型的更新

二、class对象类型的变量


        被该装饰器修饰的变量,在数据变化时会触发UI的刷新,也就是ArkTS UI中触发build()函数的调用,重新根据状态构建UI。如下更新是可以观察到的:

        1、string number boolean 类型的数据可以被监听到更新

        2、class类型 可以观察到自身的赋值的变化,和其属性赋值的变化(嵌套属性的赋值观察不到。)

一、简单类型的更新

@Entry
@Component
struct MyComponent {
  @State count: number = 0;

  build() {
    Button(`click times: ${this.count}`)
      .onClick(() => {
        this.count += 1;
      })
  }
}

        按钮Button绑定了一个点击事件,当点击事件发生时,@State修饰的变量count会加1,框架检测到状态变更,然后查询依赖该变量的组件,执行依赖该状态变量的组件的更新方法,组件更新渲染,而和该状态变量不相关的组件或者UI描述不会发生重新渲染,从而实现页面渲染的按需更新。

二、class对象类型的变量

@Entry
@Component
struct StateDemoPage {
  private flag: boolean = true;
  //string number boolean 类型的数据可以被监听到更新
  @State index: number = 0
  // class类型 可以观察到自身的赋值的变化,和其属性赋值的变化
  @State title: Model = new Model('Hello', new ClassA('World'));
  /**
   * 1 数组自身的赋值可以观察到。
   * 2 数组项的赋值可以观察到。
   * 3 删除数组项可以观察到。
   * 4 新增数组项可以观察到。
   * 5 数组项中属性的赋值观察不到。(X)
   */
  @State array: Model[] = [new Model('a', new ClassA('xx')), new Model('b', new ClassA('yy'))]

  build() {
    Row() {
      Column({ space: 12 }) {
        Text(`${this.index}`).stateTextStyle(() => {
          this.index++
        })

        Text(`${this.title.key}-${this.title.value.subtitle}`).stateTextStyle(() => {
          if (this.flag) {
            this.title = new Model('World', new ClassA('Hello'))
          } else {
            this.title.key = 'World Change'
          }
          this.flag = !this.flag
          // 嵌套的属性赋值观察不到
          // this.title.name.value = 'ArkUI'
        })

        ForEach(this.array, (item: Model, index) => {
          Row() {
            Text(item.key).width('40%').fontSize(24).backgroundColor(Color.Orange)
            Text(item.value.subtitle).width('40%').fontSize(24).fontColor(Color.Red).backgroundColor(Color.Blue)
          }.backgroundColor('#8067c8ff').transition({ type: TransitionType.All, translate: {x: 200, y: 40} })
        }, item => JSON.stringify(item))

        Button('ClickMe')
          .backgroundColor('#67c8ff')
          .fontColor(Color.White)
          .borderRadius(12)
          .height(44)
          .padding({ left: 24, right: 24 })
          .onClick(() => {
            animateTo({}, () => {
              // this.array = [new Model('dd', new ClassA('zz')), new Model('mm', new ClassA('z1z1'))]
              // this.array[0] = new Model('AA', new ClassA('xx'))
              // this.array.unshift(new Model('AA', new ClassA('xx'))) //头部插入
              // this.array.shift()//头部删除
              // this.array.push(new Model('AA', new ClassA('xx'))) //尾部插入
              // this.array.pop()//尾部删除

              //元素中属性的赋值不能被观察到[所与可被观察到的属性一起使用的话,也可以被观察到]
              this.array[0].value.subtitle = 'Nested action'
            })
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}



export class ClassA {
  public subtitle: string;

  constructor(value: string) {
    this.subtitle = value;
  }
}

export class Model {
  public key: string;
  public value: ClassA;
  constructor(key: string, value: ClassA) {
    this.key = key;
    this.value = value;
  }
}

        上例中演示了以下几种情况:

  • 数组自身的赋值可以观察到。
this.array = [new Model('dd', new ClassA('zz')), new Model('mm', new ClassA('z1z1'))]
  • 数组项的赋值可以观察到。
this.array[0] = new Model('AA', new ClassA('xx'))
  • 删除数组项可以观察到。
this.array.shift()//头部删除
this.array.pop()//尾部删除
  • 新增数组项可以观察到。
this.array.unshift(new Model('AA', new ClassA('xx'))) //头部插入
this.array.push(new Model('AA', new ClassA('xx'))) //尾部插入
  • 数组项中属性的赋值观察不到。(X)

        此情况需要说明下,如果单独像下面这样更新数据时,框架是不是检测到数据变化的,也就不会触发UI刷新:

this.array[0].value.subtitle = 'Nested action'

        但是但是但是当与其他可被观察到的行为一起更新数据时,也是能正确刷新的到UI上的呢(个人猜想:可被观察的行为能触发UI更新,UI更新时会把相关联的数据都用上,所以能更新到UI上)。


http://www.niftyadmin.cn/n/5274227.html

相关文章

vs code调试.so文件

使用vs code调试.so文件 1 vs code中安装c的debug插件2 【重要】编写launch.json3 在.so的源码中打断点4 debug模式启动进程5 attach进程6 开始调试 .so是一种动态链接库,在大型项目以及跨语言项目中经常用到。在拿到.so文件对应的源码后进行debug呢? 简…

88道Vue高频题整理(附答案背诵版)

1、请简述Vue插件和组件的区别 ? Vue的插件(Plugin)和组件(Component)是Vue.js中非常重要的两个概念,它们在功能上有着明显的差异。 Vue组件(Component): Vue组件是Vue…

[C++] 多态(下) -- 多态原理 -- 动静态绑定

文章目录 1、多态原理2、动态绑定和静态绑定3、单继承和多继承关系的虚函数表3.1 单继承中的虚函数表5.2 多继承中的虚函数表 上一篇文章我们了解了虚函数表,虚函数表指针,本篇文章我们来了解多态的底层原理,更好的理解多态的机制。 [C] 多态…

Unity中Shader测试常用的UGUI功能简介

文章目录 前言一、锚点1、锚点快捷修改位置2、使用Anchor Presets快捷修改3、Anchor Presets界面按下 Shift 可以快捷修改锚点和中心点位置4、Anchor Presets界面按下 Alt 可以快捷修改锚点位置、UI对象位置 和 长宽大小 二、Canvas画布1、UGUI中 Transform 变成了 Rect Transf…

Node.js和MySQL编写接口并进行请求

Node.js和MySQL编写接口并进行请求 一、安装Node.js:首先,确保你的计算机上已经安装了Node.js。你可以从Node.js官方网站(https://nodejs.org)下载并安装适合你操作系统的版本。 二、新建 server 文件夹作为项目根目录&#xff…

Unity3D UDP传输大文件怎么提高速度详解

前言 Unity3D是一款强大的游戏开发引擎,但是在处理大文件传输时,往往会遇到速度较慢的问题。本文将详细介绍如何通过使用UDP协议来提高大文件传输的速度,并给出相应的技术详解和代码实现。 对惹,这里有一个游戏开发交流小组&…

漏洞复现--Smartbi smartbivisionRMIServlet 接口权限绕过漏洞

免责声明: 文章中涉及的漏洞均已修复,敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直…

web前端1+x(初级)理论(158道单选题含答案)

1、以下关于在CSS中的选择器命名错误的是(B) A..boxp B.%div C.* D.table 2、给某段文字设置穿过文本的一条线,应该设置什么属性?(A) A.text-decoration B.text-align C.text-inden…