自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何監(jiān)聽(tīng)多層狀態(tài)的變化(使用@State、@Observed、@ObjectLink裝飾器)

開(kāi)發(fā) 前端
本文就為大家介紹如何配合使用@State、@Observed、@ObjectLink三個(gè)裝飾器監(jiān)聽(tīng)多層狀態(tài)變化。本例最終實(shí)現(xiàn)效果為:將工程資源文件中png格式的圖片轉(zhuǎn)換為jpg格式,并保存在設(shè)備中。由于本例不涉及UI講解,所以不在此提供UI效果。

想了解更多關(guān)于開(kāi)源的內(nèi)容,請(qǐng)?jiān)L問(wèn):

51CTO 開(kāi)源基礎(chǔ)軟件社區(qū)

https://ost.51cto.com

如何監(jiān)聽(tīng)多層狀態(tài)變化

場(chǎng)景說(shuō)明

應(yīng)用開(kāi)發(fā)過(guò)程中,當(dāng)希望通過(guò)狀態(tài)變量控制頁(yè)面刷新時(shí),大家通常想到的就是裝飾器@State,但是在嵌套場(chǎng)景下,單單使用@State并不能監(jiān)聽(tīng)到變量的狀態(tài)變化,這就引出了@Observed/@ObjectLink裝飾器。本文就為大家介紹如何配合使用@State、@Observed、@ObjectLink三個(gè)裝飾器監(jiān)聽(tīng)多層狀態(tài)變化。

概念原理

在講解具體操作前,大家先理解以下幾個(gè)概念:

  • 第一層狀態(tài)變化:指不包含嵌套關(guān)系的變量的變化,比如string、number、boolean等基礎(chǔ)數(shù)據(jù)類型的狀態(tài)變化,以及嵌套結(jié)構(gòu)中第一層變量的狀態(tài)變化。
  • 多層狀態(tài)變化:指包含嵌套關(guān)系的二層及以下變量的變化,比如嵌套類中被嵌套類的成員變量的狀態(tài)變化,嵌套數(shù)組中被嵌套數(shù)組的狀態(tài)變化等。

第一層變量的狀態(tài)變化可以用@State監(jiān)聽(tīng),二層及以下變量的狀態(tài)變化則需要使用@Observed/@ObjectLink監(jiān)聽(tīng)。以嵌套結(jié)構(gòu)舉例,如下圖:

如何監(jiān)聽(tīng)多層狀態(tài)的變化(使用@State、@Observed、@ObjectLink裝飾器)-開(kāi)源基礎(chǔ)軟件社區(qū)如何監(jiān)聽(tīng)多層狀態(tài)的變化(使用@State、@Observed、@ObjectLink裝飾器)-開(kāi)源基礎(chǔ)軟件社區(qū)

為便于理解,通過(guò)以下例子具體說(shuō)明單層和多層狀態(tài)變化:

class ClassB {
  public c: number;

  constructor(c: number) {
    this.c = c;
  }
}

class ClassA {
  // ClassB成員變量的類型為ClassA,ClassA為被嵌套類
  public b: ClassB;

  constructor(b: ClassB) {
    this.b = b;
  }
}

a: ClassA
// 變量b為ClassA的成員變量,為第一層變量,所以變量b的狀態(tài)變化即為第一層狀態(tài)變化
this.a.b = new ClassB(0)
// 變量c為被嵌套類ClassB的成員變量,變量c的狀態(tài)變化即為第二層狀態(tài)變化
this.a.b.c = 5

監(jiān)聽(tīng)第一層狀態(tài)變化

監(jiān)聽(tīng)第一層狀態(tài)變化可以使用@State修飾變量,變量發(fā)生變化后即可同步刷新UI,這是大家最常用的場(chǎng)景,為便于理解,此處舉例說(shuō)明一下:

class ClassA {
  public a:number

  constructor(a:number) {
    this.a = a;
  }
}

@Entry
@Component
struct ViewA {
  // 使用@State修飾變量class_A,以監(jiān)聽(tīng)其變化
  @State class_A: ClassA = new ClassA(0);

  build() {
    Column() {
      Row(){
        Button(`第一層變量+1`)
          .margin({top:10,right:20})
          .backgroundColor('#E8A027')
          .onClick(() => {
            // class_A的成員變量a加1,class_A發(fā)生變化
            this.class_A.a += 1;
          })
        // 將第一層變量在UI呈現(xiàn)出來(lái)
        Text(`${this.class_A.a}`)
      }
      .margin({top:50})

      Row(){
        Button(`第一層變量變?yōu)?`)
          .margin({top:10,right:20})
          .onClick(() => {
            // 將新的ClassA實(shí)例賦值給class_A,class_A發(fā)生變化
            this.class_A = new ClassA(2);
          })
        // 將第一層變量在UI呈現(xiàn)出來(lái)
        Text(`${this.class_A.a}`)
      }
    }
    .width('100%')
    .justifyContent(FlexAlign.Center)
  }
}

效果如下,如圖可以看出第一層變量發(fā)生變化后可以實(shí)時(shí)在UI呈現(xiàn)出來(lái),所以@State可以有效的監(jiān)聽(tīng)第一層變量的狀態(tài)變化:

如何監(jiān)聽(tīng)多層狀態(tài)的變化(使用@State、@Observed、@ObjectLink裝飾器)-開(kāi)源基礎(chǔ)軟件社區(qū)如何監(jiān)聽(tīng)多層狀態(tài)的變化(使用@State、@Observed、@ObjectLink裝飾器)-開(kāi)源基礎(chǔ)軟件社區(qū)

監(jiān)聽(tīng)多層狀態(tài)變化

接下來(lái),我們介紹如何使用@Observed/@ObjectLink監(jiān)聽(tīng)多層狀態(tài)變化。
在第一層狀態(tài)監(jiān)聽(tīng)的基礎(chǔ)上我們引入ClassB,構(gòu)造一個(gè)嵌套結(jié)構(gòu),從而具有多層變量,如下:

// 引入ClassB
class ClassB {
  public b: number;

  constructor(b: number) {
    this.b = b;
  }
}


class ClassA {
  // ClassA成員變量a的類型為ClassB,從而形成嵌套結(jié)構(gòu),ClassB的成員變量b為第二層變量
  public a:ClassB

  constructor(a:ClassB) {
    this.a = a;
  }
}

此時(shí)我們可以驗(yàn)證一下,如果僅使用@State是否可以監(jiān)聽(tīng)到第二層變量的變化:

// 引入ClassB
class ClassB {
  public b: number;

  constructor(b: number) {
    this.b = b;
  }
}

class ClassA {
  // ClassA成員變量a的類型為ClassB,從而形成嵌套結(jié)構(gòu),ClassB的成員變量b為第二層變量
  public a:ClassB

  constructor(a:ClassB) {
    this.a = a;
  }
}

@Entry
@Component
struct ViewA {
  // 使用@State修飾變量class_A
  @State class_A: ClassA = new ClassA(new ClassB(0));

  build() {
    Column() {
      Row(){
        // 點(diǎn)擊按鈕,第二層變量發(fā)生變化
        Button('第二層變量+1')
          .margin({top:10,right:20})
          .backgroundColor('#E8A027')
          .onClick(() => {
            // 第二層變量變化,嵌套類ClassB的成員變量b加1
            this.class_A.a.b += 1;
          })
        // 將第二層變量在UI呈現(xiàn)出來(lái)
        Text(`${this.class_A.a.b}`)
      }
      .margin({top:50})
    }
    .width('100%')
    .justifyContent(FlexAlign.Center)
  }
}

效果如下,可以看出當(dāng)?shù)诙幼兞堪l(fā)生變化時(shí),UI沒(méi)有任何變化,所以單純使用@State不能監(jiān)聽(tīng)到二層及以下變量的變化:

如何監(jiān)聽(tīng)多層狀態(tài)的變化(使用@State、@Observed、@ObjectLink裝飾器)-開(kāi)源基礎(chǔ)軟件社區(qū)如何監(jiān)聽(tīng)多層狀態(tài)的變化(使用@State、@Observed、@ObjectLink裝飾器)-開(kāi)源基礎(chǔ)軟件社區(qū)

接下來(lái)我們使用@Observed/@ObjectLink監(jiān)聽(tīng)本例中第二層變量的變化。
根據(jù)使用規(guī)則,需要使用@Observed修飾嵌套類,使用@ObjectLink修飾嵌套類的實(shí)例,且@ObjectLink不能在被@Entry修飾的組件中使用,所以我們構(gòu)建一個(gè)子組件,然后在父組件中進(jìn)行引用,具體代碼如下:

// 使用@Observed修飾ClassB
@Observed
class ClassB {
  public b: number;

  constructor(b: number) {
    this.b = b;
  }
}

class ClassA {
  // ClassA成員變量a的類型為ClassB,從而形成嵌套結(jié)構(gòu),ClassB的成員變量b為第二層變量
  public a:ClassB

  constructor(a:ClassB) {
    this.a = a;
  }
}

// 構(gòu)建子組件ViewB用于承載@ObjectLink修飾的變量
@Component
struct ViewB {
  // 使用@ObjectLink修飾ClassB的實(shí)例class_B
  @ObjectLink class_B: ClassB;
  build() {
    Row() {
      // 將ClassB的成員變量b在UI呈現(xiàn)出來(lái)
      Text(`${this.class_B.b}`)
    }
    .margin({top:100})
  }
}

@Entry
@Component
struct ViewA {
  @State class_A: ClassA = new ClassA(new ClassB(0));

  build() {
    Column() {
      ViewB({ class_B: this.class_A.a })
      Row(){
        // 點(diǎn)擊按鈕,第二層變量發(fā)生變化
        Button('第二層變量class_B.b加1')
          .margin({top:10,right:20})
          .backgroundColor('#E8A027')
          .onClick(() => {
            // 第二層變量變化,嵌套類ClassB的成員變量b加1
            this.class_A.a.b += 1;
          })
      }
      .margin({top:50})
    }
    .width('100%')
    .justifyContent(FlexAlign.Center)
  }
}

我們來(lái)看下效果:

如何監(jiān)聽(tīng)多層狀態(tài)的變化(使用@State、@Observed、@ObjectLink裝飾器)-開(kāi)源基礎(chǔ)軟件社區(qū)如何監(jiān)聽(tīng)多層狀態(tài)的變化(使用@State、@Observed、@ObjectLink裝飾器)-開(kāi)源基礎(chǔ)軟件社區(qū)

如圖,現(xiàn)在當(dāng)二層變量發(fā)生變化時(shí),可以完美的被監(jiān)聽(tīng)到,并在UI中刷新出來(lái)了。

當(dāng)然,嵌套數(shù)組等也是同樣的原理,大家可以參考官方指南進(jìn)行嘗試。

想了解更多關(guān)于開(kāi)源的內(nèi)容,請(qǐng)?jiān)L問(wèn):

51CTO 開(kāi)源基礎(chǔ)軟件社區(qū)

https://ost.51cto.com

責(zé)任編輯:jianghua 來(lái)源: 51CTO 開(kāi)源基礎(chǔ)軟件社區(qū)
相關(guān)推薦

2010-02-01 17:50:32

Python裝飾器

2022-09-14 08:16:48

裝飾器模式對(duì)象

2022-05-10 09:12:16

TypeScript裝飾器

2023-12-01 14:57:22

TCP連接

2023-12-14 08:25:14

WatchVue.js監(jiān)聽(tīng)數(shù)據(jù)

2023-11-29 16:29:09

線程java

2025-01-22 15:58:46

2022-09-19 23:04:08

Python裝飾器語(yǔ)言

2024-09-12 15:32:35

裝飾器Python

2023-08-10 17:23:39

2015-01-06 09:11:54

TCP

2024-11-04 15:30:43

Python裝飾器函數(shù)

2015-08-07 15:42:21

網(wǎng)絡(luò)監(jiān)聽(tīng)源碼

2021-09-03 08:23:21

Vue 插槽子組件

2009-12-25 18:12:43

WPF裝飾器

2023-01-06 08:55:00

2023-02-07 07:47:52

Python裝飾器函數(shù)

2016-11-01 09:24:38

Python裝飾器

2023-10-26 07:15:46

2021-11-26 12:00:07

包裝器SwiftU結(jié)構(gòu)體
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)