Harmony OS NEXT    API12

我们在搭建界面的时候都需要用到或多或少的变量,因为我们要搭建的界面有的可能是静态不需要改变的,但是大部分的还是需要进行动态的改变,有交互的界面,就要引入“状态”的概念。

例如如下的小示例

[状态1.mp4]

https://live.csdn.net/v/468256

源码如下


@Entry
@Component
struct StatusesPage {
  @State message: string = 'Hello World';

  build() {
    Column() {
      Text(this.message).fontSize(35)
      Button("Change")
        .onClick(() => { this.message = "Hello Statuses" })
    }
  }
}

那我们再修改一个小点再来看看

[状态2.mp4]

https://live.csdn.net/v/468257

源码如下


@Entry
@Component
struct StatusesPage {
  message: string = 'Hello World';

  build() {
    Column() {
      Text(this.message).fontSize(35)
      Button("Change")
        .onClick(() => { this.message = "Hello Statuses" })
    }
  }
}

想必大家都看到了message前面少了一个@State的东西, 我们称这个叫做装饰器

我们与程序之间交互出发了文本状态的变更,然后状态的改变引起了UI的重新渲染。 用装饰器修饰起来的变量发生改变会引起UI的渲染刷新。

在ArkTs中提供了很多这种装饰器,这类装饰器分为了三类(V1状态): 管理组件拥有的状态 和 管理应用拥有的状态以及其他, 如下图的导图

OK!现在清楚了状态管理的分类那接下来我们了解一些基本的装饰器的使用方法, 因为本次的内容只是对状态管理的基本了解,所以先了解基础的内容以及用法。

首先我们先了解修饰器从数据的传递形式和同步类型层面来看大致分为两类

一类为: 只读的单向传递, 另外一类为:可变的双向传递

OK!接下来我们直接开始演示加介绍

@State 从上述的示例中我们不难感觉出来,这个装饰器不需要任何条件就可以直接使用,这个装饰器属于双向传递的,也可以作为子组件单向和双向同步的数据源

@Prop这个装饰器属于单向传递被修饰的变量无法传递给父组件, 直接上演示

[状态3.mp4]

https://live.csdn.net/v/468258

源码如下:


@Entry
@Component
struct StatusesPage {
  @State message: string = 'Hello World';

  build() {
    /* 父类 */
    Column() {
      Text(this.message).fontSize(35)
      Button("Change")
        .onClick(() => { this.message = "Hello Statuses" })
      StatusesPage2({ messageChild: this.message })
    }
  }
}

@Component
struct StatusesPage2 {
  @Prop messageChild: string
  build() {
    /* 子类 */
    Column() {
      Text(this.messageChild)
        .fontSize(38)
      Button("Change Child")
        .onClick(() => {
          this.messageChild = "Child"
        })
    }
  }
}

从演示中不难看出我们的子类在点击按钮想要同步改变时发现无法“撼动”这就是他的单向关系, 因为子类中定义的变量没有初始化所以数据来源于父类,也就是"子的一切都是父亲的",但是因为父亲给了我们这个数据我们将这个数据初始化了,打个比方说"只能父亲改变你,你无法改变父亲"

@Link修饰器

这个装饰器是可变的双向传递,但是被它修饰的变量是无法赋予初值的,与上面两个装饰器不同,上面两个装饰器都可以赋予初值。

[状态四.mp4]

https://live.csdn.net/v/468259

源码如下:


@Entry
@Component
struct StatusesPage {
  @State message: string = 'Hello World';

  build() {
    /* 父类 */
    Column() {
      Text(this.message).fontSize(35)
      Button("Change")
        .onClick(() => { this.message = "Hello Statuses" })
      StatusesPage2({ messageChild: this.message })
    }
  }
}

@Component
struct StatusesPage2 {
  @Link messageChild: string
  build() {
    /* 子类 */
    Column() {
      Text(this.messageChild)
        .fontSize(38)
      Button("Change Child")
        .onClick(() => {
          this.messageChild = "Child"
        })
    }
  }
}

不难看的出,子组件中被@Link修饰的变量与父组件中对应的数据源建立双向绑定

@Provide和@Consume

这两个装饰器是"配套使用"的也是一个可双向传递的修饰器,但是我们想想看,其他的多少使用一个修饰器就差不多了,但是这个需要两个配套使用,所以它们的功能更为强大。它们支持跨组件传递状态数据,这里我们先讲基础的用法,可能后续再进行扩展。

首先我们要了解的是@Provide是提供数据的一方,对应的@Consume是代表数据接收的一方

[状态5.mp4]

https://live.csdn.net/v/468260



@Entry
@Component
struct ProvidePage {
  @Provide message: string = 'Hello World';

  build() {
    Column() {
      Text(this.message).fontSize(30)
      Button("Change")
        .onClick(() => { this.message = "我是父组件" })
      Consume1()
    }
  }
}

@Component
struct Consume1 {
  @Consume message: string

  build() {
    Column() {
      Text(this.message).fontSize(30)
      Button("Change  Child")
        .onClick(() => { this.message = "我是子组件" })
    }
  }
}

看来来这个用法和@Link差不多但是目前只是介绍基础的用法所以暂未过多的深度解析

 

本次就暂时介绍这么多

谢谢各位的观看,有错误不足的地方, 本人乐于接受各位的意见

posted on 2025-03-13 10:33  Bension  阅读(44)  评论(0)    收藏  举报