写点什么

HarmonyOS Next V2 @Local 和 @Param

作者:万少
  • 2024-12-15
    江苏
  • 本文字数:2588 字

    阅读完需:约 8 分钟

HarmonyOS Next V2 @Local 和@Param

HarmonyOS Next V2 @Local 和 @Param

@Local 背景

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


  1. @State 修饰的状态变量 可以是组件内部自己定义的

  2. @State 修饰的状态 也可以由外部父组件传递


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


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


@Local 基本使用

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


  1. @Local 只能用在 @Componentv2 修饰的组件上

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


我们对上面代码稍作修改


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


@Local 与 @State 对比

@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@Componentstruct Index {  @State num: number = 100
build() { Column() { // 父组件传递过去的数据 Son({ num: this.num }) .onClick(() => { this.num++ console.log("", this.num) }) } .height('100%') .width('100%') }}
@Componentstruct Son { num: number = 0
build() { Column() { Button(`子组件 ${this.num}`) } }}
复制代码


2. @Prop 单向同步

@Prop 单向同步


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

  2. 也不能做到双向同步


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


@Componentstruct Son {  @Prop num: number = 0
复制代码


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


class Animal {  dog: Dog = {    age: 100  }}
class Dog { age: number = 100}
@Entry@Componentstruct 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%') }}
@Componentstruct Son { @Prop dog: Dog
build() { Column() { Button(`子组件 ${this.dog.age}`) } }}
复制代码


3. @Link 双向同步

@Link 用法和 @Prop 基本一致


可以做到双向同步,但是


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

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




4. @ObjectLink

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


小结

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

@Params 介绍

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


  • @Param 装饰的变量支持本地初始化,但是不允许在组件内部直接修改变量本身。

  • 如果不本地初始化,那么必须加入 @Require

  • @Param 可以做到单向同步

  • @Param 可以检测深层次属性的修改,但是该修改在数据源上必须是整体对象的更新

  • @Params 如果也想要深度监听单个属性的修改,那么需要使用 @ObservedV2@Trace


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


class Person {  age: number = 100}@Entry@ComponentV2struct 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%')  }}
@ComponentV2struct Son { // 要么设置 @Require 表示父组件必须传递数据 // 要么设置 默认值 @Require @Param age: number build() { Column() { Button(`子组件 ${this.age}`) } }}
复制代码


总结

  1. @Local 可以看成是 @State 的替代 ,单独表示组件内部的状态

  2. @Params 可以看成 @Prop @Link @ObjectLink 的替代,更加严谨

  3. @Local 和 @Params 搭配一起使用,都只能用在 @Componentv2 修饰的自定义组件上


发布于: 刚刚阅读数: 5
用户头像

万少

关注

还未添加个人签名 2021-12-02 加入

还未添加个人简介

评论

发布
暂无评论
HarmonyOS Next V2 @Local 和@Param_鸿蒙_万少_InfoQ写作社区