0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

HarmonyOS Next V2 @Local 和@Param

万少 来源:jf_22972444 作者:jf_22972444 2025-04-02 18:27 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

HarmonyOS Next V2 @Local 和@Param

@Local 背景

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

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

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

@Entry
@Component
struct Index {
  @State num: number = 100

  build() {
    Column() {
      Text("父组件的数据 " + this.num)

      Son({ num: this.num })
      Son()
    }
    .height('100%')
    .width('100%')
  }
}

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

  build() {
    Column() {
      Button(`子组件 ${this.num}`)
        .onClick(() = > {
          this.num++
        })
    }
  }
}

image-20240718201721853

@Local 基本使用

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

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

我们对上面代码稍作修改

@Entry
@Component
struct Index {
  @State num: number = 100

  build() {
    Column() {
      Text("父组件的数据 " + this.num)

      Son({ num: this.num }) // 这里就报错啦

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

@ComponentV2 // 此处调整为 @ComponentV2
struct Son {

  // 此处调整为 @Local
  @Local num: number = 0

  build() {
    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 = 100

  build() {
    Column() {
      // 父组件传递过去的数据
      Son({ num: this.num })
        .onClick(() = > {
          this.num++
          console.log("", this.num)
        })
    }
    .height('100%')
    .width('100%')
  }
}

@Component
struct Son {
  num: number = 0

  build() {
    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 {
  @State
  animal: 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: Dog

  build() {
    Column() {
      Button(`子组件 ${this.dog.age}`)
    }
  }
}

image-20240718215929872

3. @Link 双向同步

@Link 用法和@Prop 基本一致

可以做到双向同步,但是

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

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

    class Dog {
      age: number = 100
    }
    
    @Entry
    @Component
    struct Index {
      @State
      dogList: 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: Dog
    
      build() {
        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 {
  @Local
  person: 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: number
  build() {
    Column() {
      Button(`子组件 ${this.age}`)
    }
  }
}

image-20240718222428155

总结

  1. @Local 可以看成是 @State 的替代 ,单独表示组件内部的状态
  2. @Params 可以看成 @Prop @Link @ObjectLink 的替代,更加严谨
  3. @Local 和 @Params 搭配一起使用,都只能用在 @Componentv2 修饰的自定义组件上
审核编辑 黄宇
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • HarmonyOS
    +关注

    关注

    80

    文章

    2157

    浏览量

    36284
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    uM-FPU V2 浮点协处理器:功能特性与应用指南

    uM-FPU V2 浮点协处理器:功能特性与应用指南 引言 在电子设计领域,浮点运算能力对于许多应用至关重要。Micromega Corporation 的 uM-FPU V2 浮点协处理器为
    的头像 发表于 04-11 15:15 470次阅读

    AA Boost Module V2:便捷的电源解决方案

    AA Boost Module V2:便捷的电源解决方案 在电子设计中,电源供应是一个关键问题。今天要给大家介绍的是DFRobot的独家产品——AA Boost Module V2(SKU
    的头像 发表于 03-27 12:50 191次阅读

    如何在 VisionFive v2 上使用外部 GPU?

    如果旧的 amd gpu 在 VisionFive V2 上运行,我想使用带有开源 amd 驱动程序的 amd gpu。我需要什么以及如何将 GPU 连接到 VisionFive v2
    发表于 03-13 06:38

    RDMA设计44:RoCE v2原语功能验证与分析

    它是RoCE v2协议进行信息及数据交换的核心机制,也是DUT需要实现的核心机制之一,对该功能的仿真验证需要考虑指令的提交数据包的组装及发送、数据的DMA处理等。
    的头像 发表于 02-25 09:26 308次阅读
    RDMA设计44:RoCE <b class='flag-5'>v2</b>原语功能验证与分析

    RDMA设计37:RoCE v2 子系统模型设计

    本博文主要交流设计思路,在本博客已给出相关博文160多篇,希望对初学者有用。注意这里只是抛砖引玉,切莫认为参考这就可以完成商用IP设计。 RoCE v2 子系统模型是用来模拟 RoCE v2 功能
    发表于 02-06 16:19

    RDMA设计30:RoCE v2 发送模块2

    当 RoCE v2 发送模块检测到发送队列非空时,则从发送队列中读取一个发送队列条目,并判断请求类型。根据不同的请求类型和请求长度进入不同的包生成流程,这一过程由请求状态机实现。
    的头像 发表于 01-27 11:56 813次阅读
    RDMA设计30:RoCE <b class='flag-5'>v2</b> 发送模块<b class='flag-5'>2</b>

    RDMA设计29:RoCE v2 发送及接收模块设计2

    本博文主要交流设计思路,在本博客已给出相关博文约100篇,希望对初学者有用。注意这里只是抛砖引玉,切莫认为参考这就可以完成商用IP设计。 (1)RoCE v2 发送模块 RoCE v2 发送模块
    发表于 01-26 16:47

    RDMA设计28:RoCE v2 发送及接收模块设计

    本博文主要交流设计思路,在本博客已给出相关博文约100篇,希望对初学者有用。注意这里只是抛砖引玉,切莫认为参考这就可以完成商用IP设计。 RoCE v2 发送及接收模块负责将用户指令组装为 RoCE
    发表于 01-25 10:45

    RDMA设计19:RoCE v2 发送及接收模块设计

    本博文主要交流设计思路,在本博客已给出相关博文约100篇,希望对初学者有用。注意这里只是抛砖引玉,切莫认为参考这就可以完成商用IP设计。 RoCE v2 发送及接收模块负责将用户指令组装
    发表于 01-06 08:08

    AURIX™ Audio Application Kit for AURIX™ lite Kit V2 深度解析

    AURIX™ Audio Application Kit for AURIX™ lite Kit V2 深度解析 在音频技术不断发展的今天,一款功能强大且灵活的音频应用套件对于电子工程师来说至关重要
    的头像 发表于 12-20 20:35 1445次阅读

    uIO-Stick v2 用户指南:设计、应用与安全要点

    uIO-Stick v2 用户指南:设计、应用与安全要点 在电子工程领域,接口设备对于连接不同系统和实现功能交互起着至关重要的作用。uIO-Stick v2 作为一款用于 MOTIX™ MCU 设备
    的头像 发表于 12-20 11:10 857次阅读

    RDMA设计5:RoCE V2 IP架构

    上面分析,基于RoCE v2 高速数据传输IP 的高速传输应用整体架构如图 1 所示。 图1 基于RoCE V2 IP应用的系统整体架构图 它通过 QSFP28 接口连接上位机进行
    发表于 11-25 10:34

    RDMA over RoCE V2设计1:为什么要设计它?

    基于PC-PC或GPU-GPU之间RDMA设计已有较多厂商投入,虽然有的大厂投入几年后折羽而归,但不影响PC领域成熟应用产品的推广。这里主要讨论在FPGA上设计RDMA over RoCE V2,虽然已有xilinx的ernic应用,但是性价比以及国产化需求还是有其发展空间。
    的头像 发表于 07-15 10:58 812次阅读
    RDMA over RoCE <b class='flag-5'>V2</b>设计1:为什么要设计它?

    第三届大会回顾第6期 | HarmonyOS NEXT原生智能,助力应用低成本生而智能

    原生智能是HarmonyOS NEXT的核心能力之一,通过将人工智能(AI)技术与操作系统深度融合,实现了从底层到应用层的全面智能化。HarmonyOS NEXT的原生智能是如何实现的
    的头像 发表于 07-14 18:04 1311次阅读
    第三届大会回顾第6期 | <b class='flag-5'>HarmonyOS</b> <b class='flag-5'>NEXT</b>原生智能,助力应用低成本生而智能

    第三届大会回顾第2期 | HarmonyOS NEXT内核驱动生态兼容与竞争力思考

    随着HarmonyOS NEXT生态和技术的发展,驱动框架作为北向和南向的生态中枢,有很多的机会。例如,提供更多的信息到应用层,实现精准的性能功耗控制;打破传统的分层解耦,简化关键协议、关键路径等等。
    的头像 发表于 05-19 19:17 1978次阅读
    第三届大会回顾第<b class='flag-5'>2</b>期 | <b class='flag-5'>HarmonyOS</b> <b class='flag-5'>NEXT</b>内核驱动生态兼容与竞争力思考