1、前言

我们在上一章学习了@State装饰器,@State装饰器的作用范围仅仅在当前组件,接下来,我们讨论如何从父组件中传入参数到子组件,让子组件随着父组件的状态发生变化。本章将要介绍的就是:@Props装饰器。

2、@Props装饰器

@Prop装饰的变量可以和父组件建立单向的同步关系。@Prop装饰的变量是可变的,但是变化不会同步回其父组件。

  • @Prop变量允许在本地修改和初始化,但修改后的变化不会同步回父组件。

  • 当父组件中的数据源更改时,与之相关的@Prop装饰的变量都会自动更新。如果子组件已经在本地修改了@Prop装饰的相关变量值,而在父组件中对应的@State装饰的变量被修改后,子组件本地修改的@Prop装饰的相关变量值将被覆盖。

  • @Prop装饰器不能在@Entry装饰的自定义组件中使用。

  • 装饰器允许装饰的变量类型有:string、number、boolean、enum类型。不支持any,不允许使用undefined和null。

  • 装饰的变量必须指定类型,在父组件中,传递给@Prop装饰的值不能为undefined或者null;

  • @Prop装饰的变量和父组件状态变量类型相同,即@Prop : S和@State : S

  • 虽然说@Props装饰的变量可由父组件初始化,但使用范围依旧只能在组件内访问。

核心代码结构如下:

@Component
struct Child {
// 子组件中的@Props变量,可以被父组件初始化
  @Prop count: number;
} @Entry
struct Parent {
  @State parentCount:number = 1;
  build() {
  // 此时,父组件就将本地parentCount变量传递给了子组件
  // 当parentCount发生变化时,子组件也会刷新
  Child({count: this.parentCount});
  }
}

3、@Props装饰器的简单使用Demo

以下示例是@State到子组件@Prop简单数据同步,

父组件ParentComponent的状态变量countDownStartValue初始化子组件CountDownComponent中@Prop装饰的count,

点击“Try again”,count的修改仅保留在CountDownComponent,不会同步给父组件ParentComponent。

ParentComponent的状态变量countDownStartValue的变化将重置CountDownComponent的count。

@Component
struct CountDownComponent {
@Prop count: number;
costOfOneAttempt: number = 1; build() {
Column() {
if (this.count > 0) {
Text(`You have ${this.count} Nuggets left`)
} else {
Text('Game over!')
}
// @Prop装饰的变量不会同步给父组件
Button(`Try again`).onClick(() => {
this.count -= this.costOfOneAttempt;
})
}
}
} @Entry
@Component
struct ParentComponent {
@State countDownStartValue: number = 10; build() {
Column() {
Text(`Grant ${this.countDownStartValue} nuggets to play.`)
// 父组件的数据源的修改会同步给子组件
Button(`+1 - Nuggets in New Game`).onClick(() => {
this.countDownStartValue += 1;
})
// 父组件的修改会同步给子组件
Button(`-1 - Nuggets in New Game`).onClick(() => {
this.countDownStartValue -= 1;
}) CountDownComponent({ count: this.countDownStartValue, costOfOneAttempt: 2 })
}
}
}

在上面的示例中:

  1. CountDownComponent子组件首次创建时其@Prop装饰的count变量将从父组件@State装饰的countDownStartValue变量初始化,界面如下:

  1. 按“+1”或“-1”按钮时,父组件的@State装饰的countDownStartValue值会变化,这将触发父组件重新渲染,在父组件重新渲染过程中会刷新使用countDownStartValue状态变量的UI组件并单向同步更新CountDownComponent子组件中的count值;

  1. 更新count状态变量值也会触发CountDownComponent的重新渲染,在重新渲染过程中,评估使用count状态变量的if语句条件(this.count > 0),并执行true分支中的使用count状态变量的UI组件相关描述来更新Text组件的UI显示;

  2. 当按下子组件CountDownComponent的“Try again”按钮时,其@Prop变量count将被更改,但是count值的更改不会影响父组件的countDownStartValue值;

  1. 父组件的countDownStartValue值会变化时,父组件的修改将覆盖掉子组件CountDownComponent中count本地的修改。

由于有@State装饰器的经验,学习@Props起来就得心应手了。到此,我们基本也就掌握了@Props装饰器的使用了。

趁热打铁,我们可能就会问了,@Props组件只能由父组件到子组件单向传递,那我想实现双向传递怎么办呢?那就需要用到@Link装饰器了。

4、@Link装饰器

@Link装饰器与@Props装饰器的用法几乎一样,区别只是@Props装饰器是父组件向子组件单向同步,而@Link装饰器是子组件和父组件双向同步。

我们平时使用@Link装饰器就和@Props差不多,有一个区别:@Link装饰器的属性不能本地初始化。

直接上一段Demo:

点击父组件ShufflingContainer中的“Parent View: Set yellowButton” 和 “Parent View: Set GreenButton”,可以从父组件将变化(控件长度)同步给子组件。

1.点击子组件GreenButton和YellowButton中的Button,子组件会发生相应变化,将变化同步回父组件。因为@Link是双向同步,会将变化同步给@State。

2.当点击父组件ShufflingContainer中的Button时,@State变化,也会同步给@Link,子组件也会发生对应的刷新。

代码如下:

class GreenButtonState {
width: number = 0; constructor(width: number) {
this.width = width;
}
} @Component
struct GreenButton {
@Link greenButtonState: GreenButtonState; build() {
Button('Green Button')
.width(this.greenButtonState.width)
.height(40)
.backgroundColor('#64bb5c')
.fontColor('#FFFFFF,90%')
.onClick(() => {
if (this.greenButtonState.width < 700) {
// 更新class的属性,变化可以被观察到同步回父组件
this.greenButtonState.width += 60;
} else {
// 更新class,变化可以被观察到同步回父组件
this.greenButtonState = new GreenButtonState(180);
}
})
}
} @Component
struct YellowButton {
@Link yellowButtonState: number; build() {
Button('Yellow Button')
.width(this.yellowButtonState)
.height(40)
.backgroundColor('#f7ce00')
.fontColor('#FFFFFF,90%')
.onClick(() => {
// 子组件的简单类型可以同步回父组件
this.yellowButtonState += 40.0;
})
}
} @Entry
@Component
struct ShufflingContainer {
@State greenButtonState: GreenButtonState = new GreenButtonState(180);
@State yellowButtonProp: number = 180; build() {
Column() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) {
// 简单类型从父组件@State向子组件@Link数据同步
Button('Parent View: Set yellowButton')
.width(312)
.height(40)
.margin(12)
.fontColor('#FFFFFF,90%')
.onClick(() => {
this.yellowButtonProp = (this.yellowButtonProp < 700) ? this.yellowButtonProp + 40 : 100;
})
// class类型从父组件@State向子组件@Link数据同步
Button('Parent View: Set GreenButton')
.width(312)
.height(40)
.margin(12)
.fontColor('#FFFFFF,90%')
.onClick(() => {
this.greenButtonState.width = (this.greenButtonState.width < 700) ? this.greenButtonState.width + 100 : 100;
})
// class类型初始化@Link
GreenButton({ greenButtonState: $greenButtonState }).margin(12)
// 简单类型初始化@Link
YellowButton({ yellowButtonState: $yellowButtonProp }).margin(12)
}
}
}
}

5、结语

至此,我们在@State装饰器的基础上又学习了@Props装饰器和@Link装饰器,@Props装饰器用于接受来自父组件的变量,@Link也用于接受来自父组件的变量,但额外的,@Link装饰器在子组件中被修改后,父组件中对应的值也会发生改变。

剩下的状态装饰器请持续关注 “鸿蒙UI开发快速入门 —— part08 ”

鸿蒙UI开发快速入门 —— part07:组件状态管理之@Prop/@Link装饰器的更多相关文章

  1. Transform组件C#游戏开发快速入门

    Transform组件C#游戏开发快速入门大学霸 组件(Component)可以看作是一类属性的总称.而属性是指游戏对象上一切可设置.调节的选项,如图2-8所示.本文选自C#游戏开发快速入门大学霸   ...

  2. HealthKit开发快速入门教程之HealthKit框架体系创建健康AppID

    HealthKit开发快速入门教程之HealthKit框架体系创建健康AppID HealthKit开发准备工作 在开发一款HealthKit应用程序时,首先需要讲解HealthKit中有哪些类,在i ...

  3. HealthKit开发快速入门教程之HealthKit开发概述简介

    HealthKit开发快速入门教程之HealthKit开发概述简介 2014年6月2日召开的年度开发者大会上,苹果发布了一款新的移动应用平台,可以收集和分析用户的健康数据.该移动应用平台被命名为“He ...

  4. Apple Watch开发快速入门教程

     Apple Watch开发快速入门教程  试读下载地址:http://pan.baidu.com/s/1eQ8JdR0 介绍:苹果为Watch提供全新的开发框架WatchKit.本教程是国内第一本A ...

  5. SpringBoot开发快速入门

    SpringBoot开发快速入门 目录 一.Spring Boot 入门 1.Spring Boot 简介 2.微服务 3.环境准备 1.maven设置: 2.IDEA设置 4.Spring Boot ...

  6. HealthKit开发快速入门教程之HealthKit数据的操作

    HealthKit开发快速入门教程之HealthKit数据的操作 数据的表示 在HealthKit中,数据是最核心的元素.通过分析数据,人们可以看到相关的健康信息.例如,通过统计步数数据,人们可以知道 ...

  7. 游戏控制杆OUYA游戏开发快速入门教程

    游戏控制杆OUYA游戏开发快速入门教程 1.2.2  游戏控制杆 游戏控制杆各个角度的视图,如图1-4所示,它的硬件规格是本文选自OUYA游戏开发快速入门教程大学霸: 图1-4  游戏控制杆各个角度的 ...

  8. WPF开发快速入门【7】WPF的拖放功能(Drag and Drop)

    概述 本文描述WPF的拖放功能(Drag and Drop). 拖放功能涉及到两个功能,一个就是拖,一个是放.拖放可以发生在两个控件之间,也可以在一个控件自己内部拖放.假设界面上有两个控件,一个Tre ...

  9. ReactJS入门2:组件状态

    React组件可以简单看做是包含props和states的函数. 上一节总结了创建新组建和数据属性的传递.本节主要讲解组件的状态. React认为UI是不同状态的展现.在React中,开发者只需更新组 ...

  10. 【翻译】WPF应用程序模块化开发快速入门(使用Prism+MEF)

    编译并运行快速入门 需要在VisualStudio 2010上运行此快速入门示例 代码下载:ModularityWithMef.zip 先重新生成解决方案 再按F5运行此示例 说明: 在此快速入门示例 ...

随机推荐

  1. 我是如何开发一款支持IDEA、PyCharm、Android Sutdio 等JB全家桶的摸鱼插件的

    公众号「古时的风筝」,专注于后端技术,尤其是 Java 及周边生态. 个人博客:www.moonkite.cn 大家好,我是风筝 前些天做了一款支持 Jetbrains 大部分 IDE 的摸鱼插件- ...

  2. Codeforces Round 973 (Div. 2) C

    #include <bits/stdc++.h> using namespace std; int T; int n; struct edge { int pre; int nxt; in ...

  3. Windows远程设置''不可复制''的权限

    起因: 有一个技术部门的同事需要远程其他同学的电脑进行操作,但是不允许他复制目标电脑上的文件,避免造成资料外泄 解决办法: 组策略编辑器中,设置 计算机配置 -> 管理模板 -> wind ...

  4. 《WebGL 编程指南》读书笔记(2、3章)

    完整 demo 和 lib 文件可以在 https://github.com/tengge1/webgl-guide-code 中找到. 第 2 章 第一个 WebGL 程序 function mai ...

  5. 4.2.2 等差数列的前n项和公式

    ${\color{Red}{欢迎到学科网下载资料学习 }}$ [ [基础过关系列]高二数学同步精品讲义与分层练习(人教A版2019)] ( https://www.zxxk.com/docpack/2 ...

  6. 什么是 DOM

    百度: DOM 定义:文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展置标语言的标准编程接口.它是一种与平台和语言无关的应用程序接口(API),它可 ...

  7. KubeSphere 社区双周报 | 2024.01.04-01.18

    KubeSphere 社区双周报主要整理展示新增的贡献者名单和证书.新增的讲师证书以及两周内提交过 commit 的贡献者,并对近期重要的 PR 进行解析,同时还包含了线上/线下活动和布道推广等一系列 ...

  8. http协议、web服务器-并发服务器1

    阅读目录: 1.http协议 2.Web静态服务器-1-显示固定的页面 3.Web静态服务器-2-显示需要的页面 4.Web静态服务器-3-多进程 5.Web静态服务器-4-多线程 一.HTTP协议简 ...

  9. 基于pandas的数据清洗

    数据清洗是数据科学和数据分析中非常重要的一个步骤.它指的是在数据分析之前,对数据进行预处理,以确保数据的质量和一致性.使用Python的pandas库进行数据清洗是一种常见的做法,因为pandas提供 ...

  10. TRLO: An Efficient LiDAR Odometry with 3D Dynamic Object Tracking and Removal

    arxiv | 中科院联合国科大开源 TRLO:一种结合3D动态物体跟踪与移除的高效LiDAR里程计 [TRLO: An Efficient LiDAR Odometry with 3D Dynami ...