当前位置: 首页 > news >正文

Harmony 状态管理 @Local 和 @Param

Harmony 状态管理 @Local 和 @Param

@Local 背景

@Localharmony应用开发中的v2版本中 对标**@State**的状态管理修饰器,它解决了 @State 对状态变量更改的检测混乱的问题:

  1. @State 修饰的状态变量 可以是组件内部自己定义的
  2. @State 修饰的状态 也可以由外部父组件传递

这样就导致了状态数据来源不唯一,在大型项目中会引发难易检测和维护状态的问题。如以下代码:

@Entry
@Component
struct Index {@State num: number = 100build() {Column() {Text("父组件的数据 " + this.num)Son({ num: this.num })Son()}.height('100%').width('100%')}
}@Component
struct Son {@State num: number = 0build() {Column() {Button(`子组件 ${this.num}`).onClick(() => {this.num++})}}
}

image-20240718201721853

@Local 基本使用

@Local的出现就是为了解决这一类问题

  1. @Local 只能用在 @Componentv2 修饰的组件上
  2. 被**@Local**装饰的变量无法从外部初始化(无法由父组件传递进来),因此必须在组件内部进行初始化

我们对上面代码稍作修改

@Entry
@Component
struct Index {@State num: number = 100build() {Column() {Text("父组件的数据 " + this.num)Son({ num: this.num }) // 这里就报错啦Son()}.height('100%').width('100%')}
}@ComponentV2 // 此处调整为 @ComponentV2
struct Son {// 此处调整为 @Local@Local num: number = 0build() {Column() {Button(`子组件 ${this.num}`).onClick(() => {this.num++})}}
}

image-20240718204400711

@Local与@State对比

@State@Local
参数无。无。
从父组件初始化可选。不允许外部初始化。
观察能力能观测变量本身以及一层的成员属性,无法深度观测。能观测变量本身,深度观测依赖@Trace装饰器。
数据传递可以作为数据源和子组件中状态变量同步。可以作为数据源和子组件中状态变量同步。

@Local 特别注意

  • @Local支持观测number、boolean、string、Object、class等基本类型以及Array、Set、Map、Date等内嵌类型。
  • @Local的观测能力仅限于被装饰的变量本身。当装饰简单类型时,能够观测到对变量的赋值;当装饰对象类型时,仅能观测到对对象整体的赋值;当装饰数组类型时,能观测到数组整体以及数组元素项的变化;当装饰Array、Set、Map、Date等内嵌类型时,可以观测到通过API调用带来的变化。

@Params

@Params主要表示 子组件 接收父组件传递的数据。可以和 @Local 搭配一起使用

@Params 背景

在V1版本的状态管理修饰符中,可以用来处理 父子传参的技术有:

  1. 普通属性,不需要特别的修饰符 , 不具备单向同步
  2. @Prop 单向同步,不能监听深层次属性的改变,也不能做到双向同步
  3. @Link 可以做到双向同步,但是不能监听深层次属性的改变,而且不能直接用在 列表渲染技术 - ForEach 中
  4. @ObjectLink 可以做到双向同步,但是必须和 @Observed 搭配使用 ,而且只能用在自定义组件上

1. 普通属性

普通属性,不需要特别的修饰符 , 不具备单向同步

@Entry
@Component
struct Index {@State num: number = 100build() {Column() {// 父组件传递过去的数据Son({ num: this.num }).onClick(() => {this.num++console.log("", this.num)})}.height('100%').width('100%')}
}@Component
struct Son {num: number = 0build() {Column() {Button(`子组件 ${this.num}`)}}
}

image-20240718215338082

2. @Prop 单向同步

@Prop 单向同步

  1. 不能监听深层次属性的改变
  2. 也不能做到双向同步

在上面代码基础上 加入**@Prop**,可以检测到基本类型数据的更新

@Component
struct Son {@Prop num: number = 0

但是无法检测深层次属性的改变,如

class Animal {dog: Dog = {age: 100}
}class Dog {age: number = 100
}@Entry
@Component
struct Index {@Stateanimal: Animal = new Animal()build() {Column() {// 父组件传递过去的数据Son({ dog: this.animal.dog }).onClick(() => {this.animal.dog.age++console.log("", this.animal.dog.age)})}.height('100%').width('100%')}
}@Component
struct Son {@Prop dog: Dogbuild() {Column() {Button(`子组件 ${this.dog.age}`)}}
}

image-20240718215929872

3. @Link 双向同步

@Link 用法和@Prop基本一致

可以做到双向同步,但是

  1. 不能监听深层次属性的改变

  2. 而且不能直接用在 列表渲染技术 - ForEach以下代码演示这个效果

    class Dog {age: number = 100
    }@Entry
    @Component
    struct Index {@StatedogList: Dog [] = [new Dog(), new Dog(), new Dog(), new Dog()]build() {Column() {ForEach(this.dogList, (item: Dog) => {// 此处会报错  Assigning the attribute 'item' to the '@Link' decorated attribute 'dog' is not allowed. <ArkTSCheck>Son({ dog: item }).onClick(() => {item.age++console.log("", item.age)})})}.height('100%').width('100%')}
    }@Component
    struct Son {@Link dog: Dogbuild() {Column() {Button(`子组件 ${this.dog.age}`)}}
    }
    

    image-20240718220523209

4. @ObjectLink

@ObjectLink 可以做到双向同步,但是必须和 @Observed 搭配使用 ,而且只能用在自定义组件

image-20240715182615579

小结

可以看到,如果都是使用 v1版本的这一套 父子传参的技术,是十分复杂难易直接上手使用的。

@Params 介绍

Param表示组件从外部传入的状态,使得父子组件之间的数据能够进行同步:

  • @Param装饰的变量支持本地初始化,但是不允许在组件内部直接修改变量本身。
    • 如果不本地初始化,那么必须加入 @Require
  • @Param 可以做到单向同步
  • @Param 可以检测深层次属性的修改,但是该修改在数据源上必须是整体对象的更新
  • @Params 如果也想要深度监听单个属性的修改,那么需要使用 @ObservedV2@Trace

以下代码主要演示:@Param 可以检测深层次属性的修改,但是该修改在数据源上必须是整体对象的更新

class Person {age: number = 100
}
@Entry
@ComponentV2
struct Index {@Localperson: Person = new Person()build() {Column() {Son({ age: this.person.age }).onClick(() => {this.person.age++console.log("", this.person.age)if (this.person.age === 105) {const p = new Person()p.age = 200// 整体更新,子组件可以感知到this.person = p}})}.height('100%').width('100%')}
}@ComponentV2
struct Son {// 要么设置 @Require 表示父组件必须传递数据// 要么设置 默认值@Require @Param age: numberbuild() {Column() {Button(`子组件 ${this.age}`)}}
}

image-20240718222428155

总结

  1. @Local 可以看成是 @State的替代 ,单独表示组件内部的状态
  2. @Params 可以看成 @Prop @Link @ObjectLink的替代,更加严谨
  3. @Local 和 @Params 搭配一起使用,都只能用在 @Componentv2 修饰的自定义组件上

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 深入理解TCP/IP协议:三次握手与四次挥手
  • WebRTC音视频-前言介绍
  • 海外媒体发稿-瑞典SEO破茧成蝶:从0到10的实战精要-大舍传媒
  • windows edge自带的pdf分割工具(功能)
  • 设计模式--外观模式
  • Leetcode1929. 数组串联
  • 《基于 Kafka + Quartz 实现时限质控方案》
  • Hive修改表中的某个值
  • 神经网络之多层感知机
  • Symfony表单系统详解:构建强大且灵活的表单
  • 如何在Mac下修改VSCode侧边栏字体大小
  • ASPICE过程改进原则:确保汽车软件开发的卓越性能
  • Java二十三种设计模式-抽象工厂模式(3/23)
  • Web开发:ASP.NET CORE的后端小结(基础)
  • LeetCode 算法:单词搜索 c++
  • 《Javascript数据结构和算法》笔记-「字典和散列表」
  • 【技术性】Search知识
  • Docker 笔记(1):介绍、镜像、容器及其基本操作
  • gitlab-ci配置详解(一)
  • iOS帅气加载动画、通知视图、红包助手、引导页、导航栏、朋友圈、小游戏等效果源码...
  • Java 11 发布计划来了,已确定 3个 新特性!!
  • Java到底能干嘛?
  • java中具有继承关系的类及其对象初始化顺序
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • ReactNativeweexDeviceOne对比
  • SegmentFault 2015 Top Rank
  • 百度地图API标注+时间轴组件
  • 从 Android Sample ApiDemos 中学习 android.animation API 的用法
  • 动态魔术使用DBMS_SQL
  • 前端代码风格自动化系列(二)之Commitlint
  • 入门级的git使用指北
  • 入职第二天:使用koa搭建node server是种怎样的体验
  • 删除表内多余的重复数据
  • 使用 QuickBI 搭建酷炫可视化分析
  • 试着探索高并发下的系统架构面貌
  • 腾讯视频格式如何转换成mp4 将下载的qlv文件转换成mp4的方法
  • 通过来模仿稀土掘金个人页面的布局来学习使用CoordinatorLayout
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • ​LeetCode解法汇总1410. HTML 实体解析器
  • ​LeetCode解法汇总2304. 网格中的最小路径代价
  • ‌分布式计算技术与复杂算法优化:‌现代数据处理的基石
  • (读书笔记)Javascript高级程序设计---ECMAScript基础
  • (翻译)terry crowley: 写给程序员
  • (学习日记)2024.01.19
  • (转)使用VMware vSphere标准交换机设置网络连接
  • (自适应手机端)行业协会机构网站模板
  • .NET delegate 委托 、 Event 事件
  • .net framwork4.6操作MySQL报错Character set ‘utf8mb3‘ is not supported 解决方法
  • .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地定义和使用弱事件
  • .NET/C# 中你可以在代码中写多个 Main 函数,然后按需要随时切换
  • .NETCORE 开发登录接口MFA谷歌多因子身份验证
  • .NET面试题(二)