首页 > 其他分享 >HarmonyOS (ArkTS)状态管理

HarmonyOS (ArkTS)状态管理

时间:2024-01-10 12:33:07浏览次数:27  
标签:count 状态 ArkTS Color Text height HarmonyOS num 组件

一、状态管理分为:

  • 页面级变量的状态管理   (主要用于单页面,同一个页面内不同组件之间的状态管理。)
  • 应用级变量的状态管理 (主要用于多页面,同一个应用内,不同页面之间的状态管理。例如:A页面和B页面实现数据共享)

1、页面级变量的状态管理

  @State、@Prop、@Link、@Provide、@Consume、@ObjectLink、@Observed和@Watch用于管理页面级变量的状态。

装饰器

装饰内容 

说明

@State 

基本数据类型,类,数组 

修饰的状态数据被修改时会触发组件的build方法进行UI界面更新。

(只会修改当前组件的数据,不会修改子组件数据)

@Prop  基本数据类  修改后的状态数据用于在父组件和子组件之间建立单向数据依赖关系。修改父组件关联数据时,更新当前组件的UI。 (父组件改变会同步到子组件,但子组件改变不会同步到父组件) 

@Link 

基本数据类型,类,数组 

父子组件之间的双向数据绑定,父组件的内部状态数据作为数据源,任何一方所做的修改都会反映给另一方。

(父组件改变会同步到子组件,子组件改变也会同步到父组件。注意:子组件使用@Link装饰器接收数据的话,父组件需要通过$数据传值) 

@Observed 

@Observed应用于类,表示该类中的数据变更被UI页面管理。 

@ObjectLink 

被@Observed

所装饰类的 对象 

装饰的状态数据被修改时,在父组件或者其他兄弟组件内与它 关联的状态数据所在的组件都会更新UI。(结合@Observed 使用)  (用于多层嵌套(对象套对象,数组套对象等 最深层对象的属性改变了)的属性改变时更新UI) 

@Consume 

基本数据类 型,类,数组 

@Consume装饰的变量在感知到@Provide装饰的变量更新 后,会触发当前自定义组件的重新渲染。 

@Provide 

基本数据型,类,数组 

@Provide作为数据的提供方,可以更新其子孙节点的数据,并 触发页面渲染。 

@Watch 

基本数据型,类,数组 

@Watch应用于对状态变量的监听。如果开发者需要关注某个 状态变量的值是否改变,可以使用@Watch为状态变量设置回 调函数

@State

修饰的状态数据被修改时会触发组件的build方法进行UI界面更新。

@Entry
@Component
struct Index {
  @State count:number=1
  build() {
    Stack(){
      Column() {
        Text(`${this.count}`)
          .fontSize(40)
          .fontWeight(FontWeight.Bold)

        Box({
          num:this.count,
          color:Color.Red
        })
        Box({
          num:this.count,
          color:Color.Orange
        })

        Box({
          num:this.count,
          color:Color.Pink
        })
      }
      .width('100%')
      .height('100%')
      .justifyContent(FlexAlign.Center)
      Button({type:ButtonType.Circle}){
        Text("+").fontSize(40).fontColor(Color.White)
      }.width(60)
        .height(60)
      .position({
        x:"80%",
        y:"90%"
      })
      .onClick(()=>{
        this.count++
      })
    }
  }
}

@Component
struct Box{
  private color:Color
  private num:number
  build(){
    Column(){
      Text(`${this.num}`)
        .fontSize(40)
        .fontWeight(FontWeight.Bold)
    }
    .width(120)
    .height(120)
    .backgroundColor(this.color)
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Center)
    .margin({
      top:10
    })
  }
}

 @Prop 修改后的状态数据用于在父组件和子组件之间建立单向数据依赖关系。修改父组件关联数据时,更新当前组件的UI

@Entry
@Component
struct StatePropPage {
  @State count:number=1
  build() {
    Stack(){
      Column() {
        Text(`${this.count}`)
          .fontSize(40)
          .fontWeight(FontWeight.Bold)

        Container({
          num:this.count,
          color:Color.Red
        })
        Container({
          num:this.count,
          color:Color.Orange
        })

        Container({
          num:this.count,
          color:Color.Pink
        })
      }
      .width('100%')
      .height('100%')
      .justifyContent(FlexAlign.Center)
      Button({type:ButtonType.Circle}){
        Text("+").fontSize(40).fontColor(Color.White)
      }.width(60)
      .height(60)
      .position({
        x:"80%",
        y:"90%"
      })
      .onClick(()=>{
        this.count++
      })
    }
  }
}

@Component
struct Container{
  private color:Color
  @Prop num:number   //@Prop num和count建立一个单向绑定的关系
  build(){
    Column(){
      Text(`${this.num}`)
        .fontSize(40)
        .fontWeight(FontWeight.Bold)
    }
    .width(120)
    .height(120)
    .backgroundColor(this.color)
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Center)
    .margin({
      top:10
    })
    .onClick(()=>{
      this.num++
    })
  }
}

@Link 使用$传参 注意:传参使用$

父子组件之间的双向数据绑定,父组件的内部状态数据作为数据源,任何一方所做的修改都会反映给另一方

@Entry
@Component
struct StateLinkPage {
  @State count:number=1
  build() {
    Stack(){
      Column() {
        Text(`${this.count}`)
          .fontSize(40)
          .fontWeight(FontWeight.Bold)

        Box1({
          num:$count,     //注意:子组件使用@Link装饰器接收数据的话 父组件需要通过$进行传值
          color:Color.Red
        })
        Box1({
          num:$count,
          color:Color.Orange
        })

        Box1({
          num:$count,
          color:Color.Pink
        })
      }
      .width('100%')
      .height('100%')
      .justifyContent(FlexAlign.Center)
      Button({type:ButtonType.Circle}){
        Text("+").fontSize(40).fontColor(Color.White)
      }.width(60)
      .height(60)
      .position({
        x:"80%",
        y:"90%"
      })
      .onClick(()=>{
        this.count++
      })
    }
  }
}

@Component
struct Box1{
  private color:Color
  @Link num:number   //@Link num和count建立一个双向绑定的关系
  build(){
    Column(){
      Text(`${this.num}`)
        .fontSize(40)
        .fontWeight(FontWeight.Bold)
    }
    .width(120)
    .height(120)
    .backgroundColor(this.color)
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Center)
    .margin({
      top:10
    })
    .onClick(()=>{
      this.num++
    })
  }
}

@Provide @Consume

@Provide和@Consume,应用于与后代组件的双向数据同步,应用于状态数据在多个层级之间传递的 场景。不同于上文提到的父子组件之间通过命名参数机制传递,@Provide和@Consume摆脱参数传递 机制的束缚,实现跨层级传递。

Index组件调用了SecondBox组件,SecondBox组件调用了ThirdBox组件,我们要实现的功能是Index 组件和ThirdBox组件直接的数据相互绑定 

@Entry
@Component
struct StateProvideConsumePage {
  @State count:number=1
  build() {
    Stack(){
      Column() {
        Text(`${this.count}`)
          .fontSize(40)
          .fontWeight(FontWeight.Bold)

        SecondBox({
          num:$count,     //注意:子组件使用@Link装饰器接收数据的话 父组件需要通过$进行传值
          color:Color.Red
        })
        SecondBox({
          num:$count,
          color:Color.Orange
        })

        SecondBox({
          num:$count,
          color:Color.Pink
        })
      }
      .width('100%')
      .height('100%')
      .justifyContent(FlexAlign.Center)
      Button({type:ButtonType.Circle}){
        Text("+").fontSize(40).fontColor(Color.White)
      }.width(60)
      .height(60)
      .position({
        x:"80%",
        y:"90%"
      })
      .onClick(()=>{
        this.count++
      })
    }
  }
}

@Component
struct SecondBox{
  private color:Color
  @Link num:number   //@Link num和count建立一个双向绑定的关系
  build(){
    Column(){
      ThirdBox({
        num:$num
      })
    }
    .width(120)
    .height(120)
    .backgroundColor(this.color)
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Center)
    .margin({
      top:10
    })
  }
}

@Component
struct ThirdBox{
  @Link num:number
  build(){
    Text(`${this.num}`)
      .fontSize(40)
      .fontWeight(FontWeight.Bold)
      .width(120)
      .height(120)
      .textAlign(TextAlign.Center)
      .onClick(()=>{
        console.log(`this.num=${this.num}`)
        this.num++
      })
  }
}

@Watch

@Watch应用于对状态变量的监听。如果开发者需要关注某个状态变量的值是否改变,可以使用@Watch为状态变量设置回调函数

@Watch用于监听状态变量的变化,当状态变量变化时,@Watch的回调方法将被调用。@Watch在ArkUI框架内部判断数值有无更新使用的是严格相等(===),遵循严格相等规范。当在严格相等为false的情况下,就会触发@Watch的回调。

@Watch可用于购物车计算总价,或者实现计算器功能等 

@Entry
@Component
struct StateWatchPage {
  @State @Watch("change") count:number=1
  @State @Watch("change") pow:number=2
  @State res:number=1
  change(){
    this.res=Math.pow(this.count,this.pow)
  }
  build() {
    Column() {
      Row(){
        Text('基数:' )
          .fontSize(20)
        TextInput({
          text:this.count.toString()
        })
          .type(InputType.Number)
          .layoutWeight(1)
          .height(40)
          .borderRadius(10)
          .onChange((value)=>{
            if(value==null || value==undefined || value==""){
              this.count=0
            }else{
              this.count=parseInt(value)
            }
          })
      }.margin({
        bottom:20
      })

      Row(){
        Text('次幂:')
          .fontSize(20)
        TextInput({
          text:this.pow.toString()
        }).type(InputType.Number)
          .layoutWeight(1)
          .height(40)
          .borderRadius(10)
          .onChange((value)=>{
            if(value==null || value==undefined || value==""){
              this.pow=0
            }else{
              this.pow=parseInt(value)
            }
          })
      }.margin({
        bottom:20
      })

      Row(){
        Text("结果:" + this.res)
          .fontSize(30)
      }
    }
    .width('100%')
    .height('100%')
    .padding(20)
  }
}

应用级变量的状态管理
AppStorage结合 @StorageProp @StorageLink装饰器

AppStorage包含整个应用程序中需要访问的所有状态属性,只要应用程序保持运行,AppStorage就会 保存所有属性及属性值,属性值可以通过唯一的键值进行访问。

组件可以通过装饰器将应用程序状态数据与AppStorage进行同步,应用业务逻辑的实现也可以通过接 口访问AppStorage。

AppStorage的选择状态属性可以与不同的数据源或数据接收器同步,这些数据源和接收器可以是设备 上的本地或远程,并具有不同的功能,如数据持久性。这样的数据源和接收器可以独立于UI在业务逻辑中实现 。

@StorageProp装饰器

组件通过使用@StorageProp(key)装饰的状态变量,将与AppStorage建立单向数据绑定,key标识 AppStorage中的属性键值。当创建包含@StoageProp的状态变量的组件时,该状态变量的值将使用 AppStorage中的值进行初始化。AppStorage中的属性值的更改会导致绑定的UI组件进行状态更新。 

import router from '@ohos.router'

@Entry
@Component
struct StateStorePropAppStoragePage {
  @StorageLink("num") num:number=10
  @StorageProp("count") count:number=1
  build() {
    Column() {

      Text(`count=${this.count}`).fontSize(30)
        .margin({
          top:20
        })

      Button(){
        Text(`设置StorageProp值`).fontSize(18).fontColor(Color.White)
      }.width(200)
      .height(40)
      .onClick(()=>{
        AppStorage.Set<number>("count",AppStorage.Get<number>("count")+1)
      }).margin({
        top:20
      })

      Button(){
        Text(`获StorageProp取值`).fontSize(18).fontColor(Color.White)
      }.width(200)
      .height(40)
      .onClick(()=>{
        let tempCount=AppStorage.Get<number>("count")
        console.log(tempCount.toString())
      }).margin({
        top:20
      })


      Button(){
        Text(`改变变量Count的值`).fontSize(18).fontColor(Color.White)
      }.width(200)
      .height(40)
      .onClick(()=>{
        this.count++
      }).margin({
        top:20
      })



      Text(`num=${this.num}`).fontSize(30)
        .margin({
          top:100
        })
      Button(){
        Text(`设置num的值-News页面会同步状态`).fontSize(18).fontColor(Color.White)
      }.width("96%")
      .height(40)
      .onClick(()=>{
        ++this.num
        PersistentStorage.PersistProp("num",this.num)
      }).margin({
        top:20
      })
      Button(){
        Text(`跳转到news`).fontSize(18).fontColor(Color.White)
      }.width(200)
      .height(40)
      .onClick(()=>{
        router.pushUrl({
          url:"pages/News"
        })
      }).margin({
        top:20
      })


    }.height('100%')
    .width("100%")
  }
}

@StorageLink装饰器

组件通过使用@StorageLink(key)装饰的状态变量,与AppStorage建立双向数据绑定,key为 AppStorage中的属性键值。当创建包含@StorageLink的状态变量的组件时,该状态变量的值将使用 AppStorage中的值进行初始化。在UI组件中对@StorageLink的状态变量所做的更改将同步到 AppStorage,并从AppStorage同步到任何其他绑定实例中,如PersistentStorage或其他绑定的UI组件。 

@Entry
@Component
struct StateStoreLinkAppStoragePage {
  @StorageLink("count") count:number=1
  build() {
    Column() {
      Text(`${this.count}`).fontSize(30)
        .margin({
          top:20
        })

      Button(){
        Text(`设置值-StorageLink`).fontSize(18).fontColor(Color.White)
      }.width(200)
      .height(40)
      .onClick(()=>{
        AppStorage.Set<number>("count",AppStorage.Get<number>("count")+1)
      }).margin({
        top:20
      })

      Button(){
        Text(`获取值-StorageLink`).fontSize(18).fontColor(Color.White)
      }.width(200)
      .height(40)
      .onClick(()=>{
        let tempCount=AppStorage.Get<number>("count")
        console.log(tempCount.toString())
      }).margin({
        top:20
      })

      Button(){
        Text(`改变变量Count的值`).fontSize(18).fontColor(Color.White)
      }.width(200)
      .height(40)
      .onClick(()=>{
        this.count++
      }).margin({
        top:20
      })

    }.height('100%')
    .width("100%")
  }
}

AppStorage PersistentStorage

PersistentStorage类提供了一些静态方法用来管理应用持久化数据,可以将特定标记的持久化数据链 接到AppStorage中,并由AppStorage接口访问对应持久化数据,或者通过@StorageLink装饰器来访问 对应key的变量。 

AppStorage PersistentStorage结合使用可以实现不同页面之间的数据共享。

A页面设置数据 B页面获取数据 

A页面

      Button(){
        Text("设置值")fontColor(Color.White)
      }.width("90%")
      .height(40)
      .onClick(()=>{
        PersistentStorage.PersistProp("count",this.count)
      }).margin({
        top:20
      })

B页面

      Button(){
        Text("获取值")fontColor(Color.White)
      }.width("90%")
      .height(40)
      .onClick(()=>{
        let count = AppStorage.Get<number>("count")
        console.log(`${count}`)
      }).margin({
        top:20
      })

 

1

标签:count,状态,ArkTS,Color,Text,height,HarmonyOS,num,组件
From: https://www.cnblogs.com/jerryspace/p/17956235

相关文章

  • 支付系统的心脏:简洁而精妙的状态机设计与核心代码实现
    这是《百图解码支付系统设计与实现》专栏系列文章中的第(9)篇。本篇主要讲清楚什么是状态机,简洁的状态机对支付系统的重要性,状态机设计常见误区,以及如何设计出简洁而精妙的状态机,核心的状态机代码实现等。我前段时间面试一个工作过4年的同学竟然没有听过状态机。假如你没有听过状态机......
  • 华为HarmonyOS开发之模拟器不能启动的问题(虚拟化未开启)
    如图,点击查看处理指导,根据提示修改配置后还是启动失败 查看任务管理器——》性能——》CPU 显示虚拟化未开启,需要开启开启步骤开启成功,模拟器也可以启动了 ......
  • HarmonyOS的简单介绍
    鸿蒙系统(HarmonyOS)是华为自主研发的一款面向全场景的分布式操作系统。其底层逻辑主要包括以下几个方面:分布式架构:鸿蒙系统采用了分布式架构设计,可以将不同的设备和服务进行高效整合。通过分布式技术,鸿蒙系统可以实现跨平台的功能,使得应用在不同的设备上能够获得一致的体验。分布式......
  • 应许的三种状态
    Promise的3种状态描述如下:Fulfilled-当异步请求成功完成并给出响应时Rejected-当异步请求不成功并且没有给出响应时,可能是由于网络错误,身份验证或授权错误等Pending-在请求发送和响应返回之间什么是回调函数?回调-是作为参数传递给不同函数的函数,然后在该函数体内调用constn......
  • 高可用 解决方案(有状态服务)
    众所周知,后台服务可以划分为两类,有状态和无状态。高可用对于无状态的应用来说是比较简单的,无状态的应用,只需要通过F5或者任何代理的方式就可以很好的解决。而本篇文章描述的主要是针对有状态的服务进行分析。服务端进行状态维护主要是通过磁盘或内存进行保存,比如MySQL数据库,red......
  • HarmonyOS鸿蒙操作系统架构
    HarmonyOS鸿蒙操作系统是基于微内核架构的,其核心组件包括:1.调度器(Scheduler):负责任务的调度和执行。2.内存管理(MemoryManagement):负责内存的分配、回收和保护。3.文件系统(FileSystem):负责对存储设备的访问和管理。4.设备驱动(DeviceDriver):负责硬件设备的控制和管理。5.网络......
  • 想快人一步!不得不看的《鸿蒙(HarmonyOS)学习指南》
    鸿蒙就是鸿蒙,安卓就是安卓据鸿蒙产业链人士透露,华为下一代鸿蒙5.0版本或将不再兼容安卓系统,此举意味着鸿蒙系统将退出Android生态圈,华为手机也将只支持鸿蒙系统应用。今后国内手机操作系统,将形成由安卓与iOS两大阵营演变成Android、iOS、Harmony三分天下的局面。随着鸿蒙发展速度越......
  • vue全屏状态下退出登录仍保持全屏
    根本解决不要用Location等方式跳转,使用router方式跳转即可。router跳转会导致浏览器退出全屏吗在大多数情况下,当使用前端路由(例如VueRouter或ReactRouter)进行页面跳转时,浏览器通常不会退出全屏状态。前端路由是通过JavaScript在当前页面内进行导航,而不是通过浏览器的传统导......
  • 零基础快速上手HarmonyOS ArkTS开发2---ArkTS开发实践
    ArkTS开发实践:接着上一次继续,在上一次对于ArkTS的基础知识进行了学习,依照官方的课程计划,还有两个具体的小案例需要来实践实践:实践出真知,还是非常有意义的,可以将零碎知识进行一个串连,下面就正式开撸。实践一:可刷新的排行榜页面效果:先来看一下官方对于此案例的一个实现效果图:大概包......
  • WGCLOUD v3.5.0 如何监测交换机的接口状态UP DOWN
    WGCLOUDv3.5.0开始可以监测交换机或SNMP设备的接口状态了,直接上图......