Harmony状态管理@Local和@Param

简介: Harmony状态管理@Local和@Param

Harmony 状态管理 @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++
        })
    }
  }
}

@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++
        })
    }
  }
}

@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}`)
    }
  }
}

(O~QMO1YSWQ})_ZWO[}X87N.png

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}`)
    }
  }
}

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}`)
    }
  }
}


4. @ObjectLink

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

小结

可以看到,如果都是使用 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}`)
    }
  }
}

总结

  1. @Local 可以看成是 @State的替代 ,单独表示组件内部的状态
  2. @Params 可以看成 @Prop @Link @ObjectLink的替代,更加严谨
  3. @Local 和 @Params 搭配一起使用,都只能用在 @Componentv2 修饰的自定义组件上
目录
相关文章
|
前端开发 JavaScript 安全
开源一款剪贴板跨设备共享工具
`shigen`,编程博主,擅长多种语言,近期自制了一个名为`copyhub`的工具,用于局域网内跨设备同步剪贴板。设计灵感源于对现有共享工具的安全顾虑,采用`Flask`和`Redis`实现,前端直接HTML+JS,简化架构。用户通过取件码交换内容,不涉及复杂功能。代码已开源并在个人腾讯云服务器上部署。更多详情见shigen的GitHub和哔哩哔哩频道。一起探索,每天进步!
468 1
开源一款剪贴板跨设备共享工具
HarmonyOS NEXT仓颉开发语言实战案例:电影App
周末好!本文分享使用仓颉语言重构ArkTS实现的电影App案例,对比两者在UI布局、组件写法及语法差异。内容包括页面结构、列表分组、分类切换与电影展示等。通过代码演示仓颉在HarmonyOS开发中的应用。##仓颉##ArkTS##HarmonyOS开发
|
SQL 安全 算法
网络安全与信息安全的全面解析:应对漏洞、加密技术及提升安全意识的策略
本文深入探讨了网络安全和信息安全的重要性,详细分析了常见的网络安全漏洞以及其利用方式,介绍了当前流行的加密技术及其应用,并强调了培养良好安全意识的必要性。通过综合运用这些策略,可以有效提升个人和企业的网络安全防护水平。
|
运维 Java Nacos
nacos常见问题之配置账号密码
Nacos是阿里云开源的服务发现和配置管理平台,用于构建动态微服务应用架构;本汇总针对Nacos在实际应用中用户常遇到的问题进行了归纳和解答,旨在帮助开发者和运维人员高效解决使用Nacos时的各类疑难杂症。
1324 6
|
Java Maven Spring
SpringBoot-读取配置文件(映射法)
本文是关于Spring Boot框架下读取配置文件的指南。该指南介绍了如何通过注解和属性文件来加载和访问应用程序的配置信息。Spring Boot提供了简单而强大的功能,可以轻松地加载各种类型的配置文件,并将其映射到Java对象中。通过使用@ConfigurationProperties注解,或者使用@Value注解从配置文件中读取属性值。
834 0
|
10月前
|
数据处理
鸿蒙开发:ArkTs字符串string
字符串类型是开发中非常重要的一个数据类型,除了上述的方法概述之外,还有String对象,正则等其他的用处,我们放到以后得篇章中讲述。
617 19
|
开发者 UED
鸿蒙next版开发:ArkTS组件通用属性(悬浮态效果)
在HarmonyOS 5.0中,ArkTS引入了悬浮态效果的控制属性,使开发者能为组件添加鼠标悬浮时的视觉反馈,增强用户体验。本文详解了hoverEffect属性及其常见效果(Auto、Scale、Highlight、None),并提供了示例代码,展示了如何为按钮设置悬浮效果。通过这些属性,开发者可以实现更生动和互动的界面。
1302 1
|
开发框架 前端开发 Swift
【Swift开发专栏】Swift与跨平台应用开发
【4月更文挑战第30天】Swift 在跨平台开发中优缺点并存,其代码复用性、高性能和易于集成是亮点,但生态系统限制和高学习成本是挑战。开发者可借助 SwiftUI、Combine 等工具,配合React Native、Flutter、Xamarin等框架实现跨平台。Swift 不是独立的跨平台框架,但能与其他框架结合使用,适用于不同项目需求。
561 0
|
前端开发 Java Apache
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
本文详细讲解了如何整合Apache Shiro与Spring Boot项目,包括数据库准备、项目配置、实体类、Mapper、Service、Controller的创建和配置,以及Shiro的配置和使用。
3290 2
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
|
JavaScript
Vue学习之--------插槽【默认插槽、具名插槽、作用域插槽】
这篇文章详细介绍了Vue.js中的插槽概念,包括默认插槽、具名插槽和作用域插槽的使用方式和实际应用示例,通过代码演示了如何在组件中定义和使用插槽来实现内容的灵活替换和展示。
Vue学习之--------插槽【默认插槽、具名插槽、作用域插槽】