HarmonyOS4.0系列——05、状态管理之@Prop、@Link、@Provide、@Consume,以及@Watch装饰器

news2024/11/18 9:47:50

状态管理

看下面这张图

请添加图片描述

Components部分的装饰器为组件级别的状态管理,Application部分为应用的状态管理。开发者可以通过@StorageLink/@LocalStorageLink 实现应用和组件状态的双向同步,通过@StorageProp/@LocalStorageProp 实现应用和组件状态的单向同步。

@Prop

static Prop(propName: string): any

与 AppStorage 中对应的 propName 建立单向属性绑定。如果给定的 propName 在 AppStorage 中存在,则返回与 AppStorage 中 propName 对应属性的单向绑定数据。如果 AppStorage 中不存在 propName,则返回 undefined。单向绑定数据的修改不会被同步回 AppStorage 中。
prop 是单向绑定,但父级不会跟子集进行相应

@Prop 是单向传递。

@Entry
@Component
struct Index {
  // State必须要进行初始化
  @State message: string ='Southern Wind'

  build() {
    Row() {
      Column() {
        Text(this.message)
          .textStyle()
        Button('点击')
          .backgroundColor(Color.Black)

          .onClick(()=>{
            this.message= this.message  === 'Southern Wind'? '你好' : 'Southern Wind';
          })
        StateProp({content:this.message})
      }
      .width('100%')
    }
  }
}


// 子组件
@Component
struct StateProp{
  @Prop content:string
  build(){
    Column(){
      Text('prop:'+this.content)
        .textStyle()
        .fontColor(Color.Green)
      Button('修改数据')
        .btnStyle(()=>{
          this.content = 'HarmonyOS4.0'
        })
    }
  }
}
// 文本公共样式
@Extend(Text) function textStyle() {
  .fontSize(30)
  .fontWeight(FontWeight.Bold)
}
// 按钮公共样式
@Extend(Button) function btnStyle(click:Function) {
  .backgroundColor(Color.Green)
  .fontSize(25)
  .margin(10)
  .onClick(()=>{
    click()
  })
 }

效果:
请添加图片描述

关于多个页面使用相同组件重名报错问题:
可以自己定义一个规范:
我这里用结构体名称加下划线的形式命名函数,如果文件名为 Index,那么我的按钮组件可以用Index_btnStyle

@Link

static Link(propName: string): any

与 AppStorage 中对应的 propName 建立双向数据绑定。如果给定的 propName 在 AppStorage 中存在,返回与 AppStorage 中 propName 对应属性的双向绑定数据。

双向绑定数据的修改会同步回 AppStorage 中,AppStorage 会将变化同步到所有绑定该 propName 的数据和自定义组件中。

如果 AppStorage 中不存在 propName,则返回 undefined。

以上是官方的说明,其实说白了Prop就是单项数据绑定,Link是双向数据绑定。

@Link 和@Prop 的区别

继续往下看个例子就明白了:

@Entry
@Component
struct Index {
  // State必须要进行初始化
  @State message: string = 'Southern Wind'

  build() {
    Row() {
      Column() {
        Text(this.message)
          .textStyle()
        Button('点击')
          .backgroundColor(Color.Black)

          .onClick(() => {
            this.message = this.message === 'Southern Wind' ? '你好' : 'Southern Wind';
          })
        StateProp({ content: this.message })
        // Index_link({content_link:this.message})
        // 如果是Link,则使用$+变量名进行传递
        Index_link({content_link: $message})
      }
      .width('100%')
    }
  }
}


// 子组件
@Component
struct StateProp {
  @Prop content: string
  build() {
    Column() {
      Text('prop:' + this.content)
        .textStyle()
        .fontColor(Color.Green)
      Button('修改Prop数据')
        .btnStyle(() => {
          this.content = '我是Prop数据'
        })
    }
  }
}

@Component
struct Index_link {
  @Link content_link: string
  build() {
    Column() {
      Text('link:' + this.content_link)
        .textStyle()
        .fontColor(Color.Red)
      Button('修改Link数据').btnStyle(()=>{
        this.content_link = '我是Link数据'
      })
        .backgroundColor(Color.Red)
    }
  }
}


// 文本公共样式
@Extend(Text) function textStyle() {
  .fontSize(30)
  .fontWeight(FontWeight.Bold)
}
// 按钮公共样式
@Extend(Button) function btnStyle(click: Function) {
  .backgroundColor(Color.Green)
  .fontSize(25)
  .margin(10)
  .onClick(() => {
    click()
  })
  // .click()
}

效果:
请添加图片描述

父孙组件传递 @Provide@Consume 与后代组件双向同步

父孙组件可以使用@Link来进行双向绑定,但是和子组件来说的话没法进行区分,所以需要使用@Provide@Consume来进行区分。
例:

@Entry
@Component

struct  Index{
  @Provide message:string = '我是父组件'
  build(){
    Row(){
      Column({space:20}){
        Text(this.message).IndexTextStyle()
          .onClick(()=>{
            this.message = 'Southern Wind'
          })
        Divider()
        Index_son()


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


@Component
struct Index_son{
  build(){
    Column({space:30}){
      Text('子组件').IndexTextStyle()
      Divider()
      Index_sun()
    }
  }
}

@Component
struct Index_sun{
  @Consume message:string
  build(){
    Column(){
      Text('孙组件' + this.message).IndexTextStyle()
        .onClick(()=>{
          this.message = 'HarmonyOS 4.0'
        })

    }
  }
}

@Extend(Text) function IndexTextStyle() {
  .fontSize(30)
}

请添加图片描述

其中@Provide装饰的变量是在祖先节点中,可以理解为被“提供”给后代的状态变量。@Consume装饰的变量是在后代组件中,去“消费(绑定)”祖先节点提供的变量。

** @Provide/@Consume装饰的状态变量有以下特性:**

  • @Provide装饰的状态变量自动对其所有后代组件可用,即该变量被“provide”给他的后代组件。由此可见,@Provide的方便之处在于,开发者不需要多次在组件之间传递变量。
  • 后代通过使用@Consume去获取@Provide提供的变量,建立在@Provide@Consume之间的双向数据同步,与@State/@Link不同的是,前者可以在多层级的父子组件之间传递。
  • @Provide@Consume可以通过相同的变量名或者相同的变量别名绑定,变量类型必须相同。
// 通过相同的变量名绑定
@Provide a: number = 0;
@Consume a: number;

// 通过相同的变量别名绑定
@Provide('a') b: number = 0;
@Consume('a') c: number;

如果@Provide@Consume绑定的变量名不相同,则可以通过变量别名来区分。

// 通过相同的变量别名绑定
@Provide('a') b: number = 0;
@Consume('d') c: number

@Watch:状态变量更改通知

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

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

@Entry
@Component
struct Index {
  @State @Watch('change') count:number = 0
  @State num:number = 2
  @State total:number = 0
  change(){
    this.total = Math.pow(this.count,this.num)
  }
  build() {
    Row(){
      Column({space:20}) {
        Text(`公式:${this.count}^${this.num}=${this.total}`).fontSize(30).fontColor(Color.Blue)
        Divider()
        Text('数字:'+this.count)
          .fontSize(30)
          .onClick(()=>{
            this.count ++
          })
        Divider()
        Text('次方:' + this.num).fontSize(25)
          .onClick(()=>{
            this.num ++
          })
        Divider()
        Text('结果:'+this.total).fontSize(40)
      }.width('100%')
    }.height('100%')
  }
}

请添加图片描述

当点击次方为文本时无法进行监听,这是因为num只是定义了双向绑定,没有设置状态监听

这时需要将num 添加监听器

 @State @Watch('change') num:number = 0

效果:

当点击次方为文本时无法进行监听,这是因为num只是定义了双向绑定,没有设置状态监听

这时需要将num 添加监听器

 @State @Watch('change') num:number = 0

效果:
请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1384982.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智能路由器中的 dns.he.net可使用自定义域名的免费 DDNS 服务配置方法

今天介绍的这个是可以使用自定义域名同时支持使用二级域名的免费DDNS服务 dns.he.net的动态DDNS服务的配置方法, 这个服务相对还是比较稳定的, 其配置也和其他的DDNS服务有些不太一样, 首先他的主机名: 这里需要设置为登录后分配的区域域名: ipv6.he.net 然后就是 DDNS 用户…

cad二次开发autolisp(一)

文章目录 一、概述1.1 简介1.2 打开编辑器1.3 调试页面 二、数据类型三、函数3.1 用户函数 四、语句4.1 常规语句4.2 流程控制语句 五、图元操作5.1 定义5.2 图元选择5.3 图元属性列表 一、概述 1.1 简介 简介:cad 二次开发语言,后缀名*.lsp适用于编写…

tda7294引脚功能和电压_三款tda7294应用电路

tda7294引脚功能 1脚为待机端; 2脚为反相输入端; 3脚为正相输入端; 4脚接地; 5、11、12脚为空脚; 6脚为自举端; 7脚为Vs(信号处理部分); 8脚为-Vs(信号…

分布式计算平台 Hadoop 简介

Hadoop简介 Hadoop是一种分析和处理大数据的软件平台,是一个用Java语言实现的Apache的开源软件框架,在大量计算机组成的集群中实现了对海量数据的分布式计算。其主要采用MapReduce分布式计算框架,包括根据GFS原理开发的分布式文件系统HDFS、…

解锁 JavaScript 数组的强大功能:常用方法和属性详解(上)

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…

使用Qt连接scrcpy-server控制手机

Qt连接scrcpy-server 测试环境如何启动scrcpy-server1. 连接设备2. 推送scrcpy-server到手机上3. 建立Adb隧道连接4. 启动服务5. 关闭服务 使用QTcpServer与scrcpy-server建立连接建立连接并视频推流完整流程1. 开启视频推流过程2. 关闭视频推流过程 视频流的解码1. 数据包协议…

C++进阶--AVL树

AVL树 一、AVL树的概念二、AVL树节点的定义三、AVL树的插入四、AVL树的旋转4.1 左单旋4.2 右单旋4.3 左右双旋4.4 右左双旋 五、AVL树的验证六、AVL树的删除七、AVL树的性能七、完整代码7.1 AVLTree.h 一、AVL树的概念 二叉搜索树虽可以缩短查找的效率,但如果数据有…

命令行登录Mysql的详细讲解

目录 前言1. 本地登录2. 远程登录3. 拓展 前言 对于命令行登录Mysql一般都是用mysql -u root -p 但对于如何远程登陆,一直其他的参数还是有些盲区,对此总结科普 对于登录过程中出现的问题,可看我之前的文章: 服务器 出现ERROR …

CTF伪随机数爆破

要了解伪随机数的爆破首先你的先知道什么是PHP种子, 借用在rand()函数中,我们可以通过设置随机数种子来影响随机数的生成。例如,在rand()函数中加入了随机数种子编码后,每次运行程序将会生成同样的随机整数序列。这个就是伪随机数…

Python实现对角但非同一性协方差结构回归模型(WLS算法)项目实战

说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 WLS回归分析是一种常用的回归分析方法,通过对数据进行加权处理,可以更准确地评…

CNN:Convolutional Neural Network(上)

目录 1 为什么使用 CNN 处理图像 2 CNN 的整体结构 2.1 Convolution 2.2 Colorful image 3 Convolution v.s. Fully Connected 4 Max Pooling 5 Flatten 6 CNN in Keras 原视频:李宏毅 2020:Convolutional Neural Network 1 为什么使用…

计算机毕业设计 基于Java的国产动漫网站的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…

HCIP 重发布

拓扑图&IP划分如下: 第一步,配置接口IP&环回地址 以R1为例,R2~R4同理 interface GigabitEthernet 0/0/0 ip address 12.1.1.1 24 interface GigabitEthernet 0/0/1 ip address 13.1.1.1 24 interface LoopBack 0 ip address 1.1.1.…

redis7部署集群

前言: redis部署集群常见的一般有三种模式:主从模式,Sentinel(哨兵模式),Redis Cluster(高可用Cluster集群),根据不同的需求可自定义选择部署方式。 Redis 主从模式&…

开发实践5_后台管理^/ 分_页器

以下学习 朔宁夫 开发课 。(Python) 一 基本使用 创建超级用户 terminal // python manage.py createsuperuser 访问地址 //Log in | Django site adminhttp://127.0.0.1:8000/admin/login/?next/admin/ superuserr login django自带admin功能。其…

深入理解 go reflect - 要不要传指针

在我们看一些使用反射的代码的时候,会发现,reflect.ValueOf 或 reflect.TypeOf 的参数有些地方使用的是指针参数,有些地方又不是指针参数, 但是好像这两者在使用上没什么区别,比如下面这样: var a 1 v1 :…

你好2024,OpenStreetMap 20 周岁

2004年,OpenStreetMap在英国诞生。2024年,OpenStreetMap 满 20 周岁,其愿景是创建一个免费的、可编辑的世界地图。当时,地图数据的获取往往受到限制或价格昂贵1。 经过20年的发展,该数据集合成为了最为全面的街道级别开…

压缩编码之离散余弦变换(DCT)之不同块大小对图像质量和压缩效果的影响的python实现

原理 离散余弦变换(DCT)是一种在图像压缩中广泛使用的技术,特别是在JPEG图像格式中。 离散余弦变换(DCT)的作用:DCT的主要目的是将图像从空间域(即像素表示)转换到频率域。在频率域…

【MATLAB随笔】GUI编程(未完结)

文章目录 一、创建图窗1.1 figure 函数详解1.11 窗口标识1.12 窗口外观1.13 位置和大小 二、xxx 一、创建图窗 跟很多GUI编程一样的,先创建一个基本的图窗,然后再添加按钮、文章、标签,绑定函数等等,比如python的tkinter。 MATL…

ES数据聚合

1.数据聚合 聚合(aggregations)可以让我们极其方便的实现对数据的统计、分析、运算。例如: 什么品牌的手机最受欢迎? 这些手机的平均价格、最高价格、最低价格? 这些手机每月的销售情况如何? 实现这些…