装饰器,状态管理和if判断(HarmonyOS学习第六课)

@Builder装饰器-自定义构建函数

前面介绍了如何创建一个自定义组件。该自定义组件内部UI结构固定,仅与使方法进行数据传递。ArkUI还提供了一种更轻量的UI 元素复用机制@Builder,@Builder

所装饰的函数遵循build( )函数语法规则,开发者可以将重复使用的UI 元素抽象成一个方法,在 build 方法里调用。 为了简化语言,我们将@Builder 装饰的函数也称为“自定义构建函数”。从API version 9开始,该装饰器支持在ArkTS卡片中使用。

装饰器使用说明:

语法的定义

@Builder MyBuilderFunction( ){...}

使用方法

this.MyBuilderFunction(){...}

  • 允许在自定义组件内定义一个或多个@Builder 方法,该方法被认为是该组件的私有、特殊类型的成员函数。

  • 自定义构建函数可以在所属组件的build 方法和其他自定义构建函数中调用,但不允许在组件外调用。

  • 在自定义函数体中,this指代当前所属组件,组件的状态变量可以在自定义构建函数内访问。建议通过this访问自定义组件的状态变量而不是参数传递

全局自定义构建函数

语法的定义

@BUilder function MyGlobalBuilderFunction(){...}

使用方法

MyGlobalBuilderFunction()
  • 全局的自定义构建函数可以被整个应用获取,不允许使用this和bind方法。

  • 如果不涉及组件状态变化,建议使用全局的自定义构建方法

参数传递规则

自定义构建函数的参数传递有按值传递和按引用传递两种,均需遵守以下规则:

参数的类型必须与参数声明的类型一致,不允许undefined、nu1l和返回undefined、null的表达式

引用传参(最常用)

//自定义一个构建函数
//引用传参使用$$符号
@Builder
function  MyBulilder($$:{username:string}){
​
//用的时候也要使用$$Column(){Text(`hello ${$$.username}`).fontSize(40).margin(20)}
}
​
@Entry
@Component
​
struct  Parent{
​@State person_name: string='张三'
​build(){Column(){Divider()MyBulilder({username: this.person_name})Button('改变值').onClick(()=>{this.person_name ='李四'})}}
}

值传参(了解 并不实用)

//自定义一个构建函数
//按值传参
@Builder
function  MyBulilder(username:string){
​
​Column(){Text(`hello ${username}`).fontSize(40).margin(20)}
}
​
@Entry
@Component
​
struct  Parent{
​@State person_name: string='张三'
​build(){Column(){Divider()MyBulilder(this.person_name)Button('改变值').onClick(()=>{this.person_name ='李四'})}}
}

状态管理

状态管理概述

在前文的描述中,我们构建的页面多为静态界面。如果希望构建一个动态的、有交互的界面,就需要引入“状态”的概念

在本章节开始的案例中,用户与应用程序的交互触发了文本状态变更,状态变更引起了UI 渲染,UI 从“Hello world”变更为“Hello rkUI”,这个过程就用到了状态。

在声明式UI编程框架中,UI是程序状态的运行结果,用户构建了一个U模型,其中应用的运行时的状态是参数。当参数改变时,UI作为返回结果,也将进行对应的改变。这些运行时的状态变化所带来的UI的重新渲染,在ArkUI中统称为状态管理机制。

自定义组件拥有变量,变量必须被装饰器装饰才可以成为状态变量,状态变量的改变会引起UI的渲染刷新。如果不使用状态变量,UI只能在初始化时渲染,后续将不会再刷新。下图展示了state和iew(UI)之间的关系

  • View(UI):UI 渲染,指将build 方法内的 UI 描述和@Builder 装饰的方法内的UI 描述映射到界面。

  • state:状态,指驱动U更新的数据。用户通过触发组件的事件方法,改变状态数据。状态数据的改变,引起UI的重新渲染。

基本概念

  • 状态变量:被状态装饰器装饰的变量,状态变量值的改变会引起UI的染更新。示例:@State num: number=1,其中,@State是状态装饰器,num是状态变量。

  • 常规变量:没有被状态装饰器装饰的变量,通常应用于辅助计算。它的改变永远不会引起UI的刷新。以下示例中increaseBy 变量为常规变量。

  • 数据源/同步源:状态变量的原始来源,可以同步给不同的状态数据。通常意义为父组件传给子组件的数据。以下示例中数据源为count:1。

  • 命名参数机制:父组件通过指定参数传递给子组件的状态变量,为父子传递同步参数的主要手段。示例:CompA:({aPrp:this.aProp})。

  • 从父组件初始化:父组件使用命名参数机制,将指定参数传递给子组件。子组件初始化的默认值在有父组件传值的情况下,会被覆盖。

  • 初始化子节点:父组件中状态变量可以传递给子组件,初始化子组件对应的状态变量。

  • 本地初始化:在变量声明的时候赋值,作为变量的默认值。示例:@statecount:number =0

管理组件拥有的状态

@State装饰器-组件内状态

@state 装饰的变量,或称为状态变量,一旦变量拥有了状态属性,就和自定义组件的渲染绑定起来。当状态改变时,UI会发生对应的渲染改变。

在状态变量相关装饰器中,@state是最基础的,使变量拥有状态属性的装饰器,它也是大部分状态变量的数据源。从Pversion9开始,该装饰器支持在ArkTs 卡片中使用。

概述

@State装饰的变量,与声明式范式中的其他被装价变量一样,是私有的,只能从组件内部访问,在声明时必须指定其类型和本地初始化。初始化也可选择使用命名参数机制从父组件完成初始化。

装饰器使用说明

使用场景

装饰简单类型的变量 以下示例为@state装饰的简单类型,count被@state装饰成为状态变量,count的改变引起Button组件的刷新:

  1. 当状态变量count改变时,查询到只有Button组件关联了它;

  2. 执行Button组件的更新方法,实现按需刷新。

示例

点击修改姓名将会在张三,李四之间进行切换

点击修改年龄将会按照你设定的规则进行年龄的加减

当子组件上传参数的时候将使用子组件的参数

当没有的时候默认是父组件的数据

@Prop装饰器-父子单项同步

@Prop 装饰的变量可以和父组性建立单向的同步关系。@Prop装饰的变量是可变但是变化不会同步回其父组件。从API version 9开始,该装饰器支持在rkTS 卡中使用。

概述

  • @Prop 装饰的变量和父组件建立单向的同步关系:

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

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

限制条件

  • @Prop 修饰复杂类型时是深拷贝,在拷贝的过程中除了基本类型、Map、Set、Date、Array 外,都会丢失类型。

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

装饰器使用规则说明

使用场景:

父组件@State 到子组件@Prop简单数据类型同步

以下示例是@state 到子组件@Prop 简单数据同步,父组件ParentComponent的状态变量 countDownstartValue 初始化子组件 CountDowncomponent 中eprop 装饰的 count,点击“Try again”,,count 的修改仅保留在 CountDownComponent不会同步给父组件ParentComponent。

ParentComponent的状态变量countDownstartValue 的变化将重冒CountDownComponent的count。

代码:

@Component
struct MyChid{@Propage: number  =33private increase: number=1 //私有build(){Column(){if (this.age>=18){Text(`已经age成年了:${this.age}`).height(80)}else{Text(`age未成年了:${this.age}`).height(80)}Button('-修改子组件age').onClick(()=>{this.age-=this.increase}).height(80).width(250).margin(5)}}
}
​
@Entry
@Component
struct Myparent {@Stateinit_age: number =16
​build(){Column(){Text(`父组件初始值:${this.init_age}`).height(80)
​Button('+修改父组件age').onClick(()=>{this.init_age+=1}).height(80).margin(5).width(250)
​Divider()MyChid({age:this.init_age,increase:2})}}
}

@Link装饰器-父子双向同步

子组件中被@Link 装饰的变量与其父组件中对应的数据源建立双向数据绑定。从APIversion 9开始,该装饰器支持在ArkTS卡片中使用。

需要注意:@Link 装饰的变量与其父组件中的数据源共享相同的值。@Link 装饰器不能在@Entry 装饰的自定义组件中使用。

代码示例展示:

//自定义按钮的信息类型
class ButtonState{value:string;width:number=0;
​constructor(value:string, width:number){this.value = value;this.width = width;}
}
​
​
@Component
​
struct MyChildGreenButton{//拥有 绿色按钮的组件,Link装饰器 实现双向同步@LinkbuttonState:ButtonState   //自定义对象类型
​build(){Button(`${this.buttonState.value}`).width(this.buttonState.width).height(150).backgroundColor(Color.Green).onClick(()=>{//点击按钮  实现宽度的变化if(this.buttonState.width<700){this.buttonState.width+=100}else {//按钮宽度回到初始值this.buttonState = new ButtonState('绿色按钮',100)}})}
}
​
​
@Component
struct MyChildRedButton{//拥有 红色按钮的组件,Link装饰器 实现双向同步@Linkvalue: string@LinkbuttomWidth: number;
​build(){Button(`${this.value}`).width(this.buttomWidth).height(150).backgroundColor(Color.Red).onClick(()=>{//点击按钮  实现宽度的变化if(this.buttomWidth<700){this.buttomWidth+=100}else {//按钮宽度回到初始值this.buttomWidth = 100}})}
}
​
@Entry
@Component
struct MYParent{@State parentGreenButton:ButtonState=new ButtonState('一号',100)  //状态变量@State parentRedValue: string = '二号子组件'  //状态变量@State parentRedWidth: number = 200   //状态变量  //绿色按钮的宽度
​build(){Column(){//父组件中调整按钮宽度Button(`父组件中修改绿色按钮的宽度:${this.parentGreenButton.width}`).onClick(()=>{this.parentGreenButton.width = this.parentGreenButton.width < 700 ? this.parentGreenButton.width+100:100})
​Button(`父组件中修改红色按钮的宽度:${this.parentRedWidth}`).onClick(()=>{this.parentRedWidth = this.parentRedWidth < 700 ? this.parentRedWidth+100:100})
​Divider()
​MyChildGreenButton({buttonState:$parentGreenButton})  //传递Link装饰器的变量时候加 $ 符号MyChildRedButton({value:$parentRedValue,buttomWidth:$parentRedWidth})}}
}

if/else 条件渲染

ArkTS 提供了渲染控制的能力。条件渲染可根据应用的不同状态,使用if、else 和else if 渲染对应状态下的UI内容。从API version 9开始,该接口支持在 ArkTS卡片中使用。

使用规则

  • 支持if、else和else if 语句。

  • if、else if 后跟随的条件语句可以使用状态变量

  • 允许在容器组件内使用,通过条件渲染语句构建不同的子组件。

  • 条件渲染语句在涉及到组件的父子关系时是“透明”的,当父组件和子组件之间存在一个或多个if语句时,必须遵守父组件关于子组件使用的规则。

  • “每个分支内部的构建函数必须遵循构建函数的规则,并创建一个或多个组件。无法创建组件的空构建函数会产生语法错误。

  • 某些容器组件限制子组件的类型或数量,将条件渲染语句用于这些组件内时,这些限制将同样应用于条件渲染语句内创建的组件。例如,Grid容器组件的子组件仅支持GridItem 组件,在Grid 内使用条件渲染语句时,条件渲染语句内仅允许使用GridItem组件

更新机制

当if、else if 后跟随的状态判断中使用的状态变量值变化时,条件渲染语句会进行更新,更新步骤如下:

  1. 评估if和else if的状态判断条件,如果分支没有变化,请无需执行以下步骤。如果分支有变化,则执行2、3步骤:

  2. 删除此前构建的所有子组件。

  3. 执行新分支的构造函数,将获取到的组件添加到if 父容器中。如果缺少适用的 else分支,则不构建任何内容。

    条件可以包括 Typescript 表达式。对于构造函数中的表达式,此类表达式不得更改应用程序状态。

使用if进行条件渲染

if 语句的每个分支都包含一个构建函数。此类构建函数必须创建一个或多个子组件。在初始渲染时,if语句会执行构建函数,并将生成的子组件添加到其父组件中。

“每当if或else if条件语句中使用的状态变量发生变化时,条件语句都会更新并重新评估新的条件值。如果条件值评估发生了变化,这意味着需要构建另一个条件分支。此时ArkUI 框架将:

  1. 删除所有以前渲染的(早期分支的)组件。

  2. 执行新分支的构造函数,将生成的子组件添加到其父组件中

代码演示

分为两种 :第一种 点击“是否真假的按钮的时候” 计数器的值会归零

//定义子组件
@Component
struct MyChild{
​//计数器@State   counter:number=0label: string;
​build(){Row(){Text(`${this.label}`).width(100).height(100).fontSize(20)
​
​Button(`计数器的值:${this.counter}`).width(200).height(60).onClick(()=>{this.counter += 1;})}}
}
​
@Entry
@Component
struct MyParent{@State flag:boolean=false;build(){Column(){//根据判断决定子组件if(this.flag){MyChild({label:'zhenzhen'})}else {MyChild({label:'jiajia'})}Divider()Button(`是否真假:${this.flag}`).width(300).height(60).fontSize(30).margin(40).onClick(()=>{this.flag=!this.flag})}}
}

第二种 点击是否真假的时候计数器的值不会进行更新归零

//定义子组件
@Component
struct MyChild{
​//计数器@Link counter:number;label: string;
​build(){Row(){Text(`${this.label}`).width(100).height(100).fontSize(20)
​
​Button(`计数器的值:${this.counter}`).width(200).height(60).onClick(()=>{this.counter += 1;})}}
}
​
​
@Entry
@Component
struct MyParent{@State flag:boolean=false;@State parentCount: number=0build(){Column(){//根据判断决定子组件if(this.flag){MyChild({counter:$parentCount,label:'zhenzhen'})}else {MyChild({counter:$parentCount,label:'jiajia'})}Divider()Button(`是否真假:${this.flag}`).width(300).height(60).fontSize(30).margin(40).onClick(()=>{this.flag=!this.flag})}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/846530.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

制作ChatPDF之后端Node搭建(三)

后端Node搭建 接上篇:制作ChatPDF之前端Vue搭建&#xff08;二&#xff09; 项目结构 下面是项目的结构图&#xff0c;包括前端 (Vue.js) 和后端 (Node.js) 的项目结构。 pdf-query-app/ ├── frontend/ │ ├── public/ │ │ ├── index.html │ ├── sr…

[Qt学习笔记]Qtxlsx在Qt下的配置和调用

背景分析 Qt操作Excel文件一般有QAxObject和QtXlsx两种方法&#xff0c;前者需要调用wps或office组件进行读写操作&#xff0c;具有一定的局限性&#xff0c;下面列出两种方法的优缺点对比 QAxObject&#xff1a; 优点&#xff1a;支持xls和xlsx等版本。office组件读写速度快&…

Java Map遍历方法(Map的Iterator原理)

Map中存放数据的Key-Value实质上就是Node节点&#xff0c;而 底层是hash数组和链表(或树)&#xff0c;不容易遍历。 一、containsKey() 和 get()查找元素 这两个方法可以获得信息&#xff0c;但是依旧不能轻松遍历。 containsKey()方法判断对应的key是否存在&#xff1b; get()…

浔川python社获得全网博主原力月度排名泸州地区第二名!

今日&#xff0c;浔川python社在查看全网博主原力月度排名泸州地区时&#xff0c;一看就震惊啦&#xff01; 全网博主原力月度排名泸州地区排名榜单 全网博主原力月度排名泸州地区第二名为&#xff1a;浔川python社。 感谢粉丝们的支持&#xff01;浔川python社还会继续努力&a…

【文献阅读】汽车上的信息安全工程

文章目录 前言 基本概念 信息安全评估 信息安全措施 测试验证 参考文献 前言 见《汽车电子——产品标准规范汇总和梳理&#xff08;信息安全&#xff09;》 基本概念 道路车辆信息安全 cybersecurity 使资产受到充分保护&#xff0c;免受道路车辆相关项、其功能及其电气或…

vue3-调用API实操-调用开源头像接口

文档部分 这边使用是开源的API 请求地址: &#xff1a;https://api.uomg.com/api/rand.avatar 返回格式 : json/images 请求方式: get/post 请求实例: https://api.uomg.com/api/rand.avatar?sort男&formatjson 请求参数 请求参数说明 名称必填类型说明sort否strin…

3DMAX建筑生长动画插件PolyFX安装使用方法

3DMAX建筑生长动画插件PolyFX安装使用教程 PolyFX插件是一个功能强大的工具&#xff0c;它可以将对象分解为片段并根据需要设置动画。它有许多用于微调动画的选项和一些附加工具。这是制作宣传视频、游戏开发等的绝佳解决方案。 【版本要求】 3ds max 2010-2025&#xff08;不…

西门子电梯控制保姆级教程

一、电梯运行控制 1.电梯控制系统结构 可以理解是通过ip进行访问的 2.基于PLCSIM Adv与电梯仿真软件的控制环境搭建 虽然都是用一台电脑来控制&#xff0c;但是还是用以太网来连接 在FC块里面也要用两个DB块来放输入和输出 二、电梯对象的分析 在eet里面&#xff0c;用手动控制…

探讨大米自动化生产线包装设备的智能化发展趋势

随着科技的飞速发展&#xff0c;智能化已经成为各行各业转型升级的重要方向。在大米生产领域&#xff0c;自动化生产线包装设备的智能化发展更是引领着粮食产业的未来潮流。星派将从智能化技术、市场需求、发展趋势等方面&#xff0c;探讨大米自动化生产线包装设备的智能化发展…

LeetCode 算法:找到字符串中所有字母异位词c++

原题链接&#x1f517;&#xff1a;找到字符串中所有字母异位词 难度&#xff1a;中等⭐️⭐️ 题目 给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符…

Python高阶学习记录

文章导读 阅读本文需要一定的python基础&#xff0c;部分知识点是对python入门篇学习记录和python并发编程学习记录的深入探究&#xff0c;本文记录的Python知识点包括函数式编程&#xff0c;装饰器&#xff0c;生成器&#xff0c;迭代器&#xff0c;正则表达式&#xff0c;内存…

eNSP——两台电脑通过一根网线直连通信

一、拓扑结构 二、电脑配置 ip和子网掩码&#xff0c;配置两台电脑处于同一网段 三、测试 四、应用 传文件等操作&#xff0c;可以在一台电脑上配置FTP服务器

Java零基础-顺序结构

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

高清矩阵是什么?

在数学中&#xff0c;矩阵是一个按照长方阵列排列的复数或实数集合&#xff0c;最早来自于方程组的系数及常数所构成的方阵。如图为m行n列的矩阵&#xff1a; 由此延伸可以想到矩阵图片是把一个三维空间分切成多个行和列的区域进行图像捕获&#xff0c;将捕获图像再进行拼合成为…

关于苹果发布IOS18系统,以及Siri升级贾维斯

随着科技的不断进步&#xff0c;手机操作系统也在持续升级&#xff0c;为用户提供更加智能化、便捷化的体验。近期&#xff0c;苹果公司即将推出的iOS 18系统引起了广泛关注。作为iPhone历史上的重大更新&#xff0c;iOS 18系统带来了众多新功能&#xff0c;将进一步提升iPhone…

2024-6-2 石群电路-21

2024-6-2&#xff0c;星期日&#xff0c;天气&#xff1a;阴&#xff0c;心情&#xff1a;晴。今天没什么特别的事情发生&#xff0c;心情还是一如既往的好&#xff0c;明天就周一啦&#xff0c;虽然我暂时不用上班&#xff0c;但是希望大家新的一周元气满满~ 今日观看了石群老…

STL中vector动态二维数组理解(杨辉三角)

题目链接&#xff1a;118.杨辉三角 题目描述&#xff1a; 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 题目指要&#xff1a; 本题的主要目的是理解vector<vector<int&…

18 跨团队 没有汇报线的人和事就是推不动?

在“05 | 大项目&#xff1a;把握关键点&#xff0c;谋定而后动”和“11 | 勤沟通&#xff1a;在信任的基础上&#xff0c;让沟通简单”两讲中&#xff0c;我提过“跨团队”这件事&#xff0c;很多同学带团队之后&#xff0c;无法回避的一个问题就是“跨团队协作”&#xff0c;…

2024/6/2 英语每日一段

However, they denied Hirst had been deliberately misleading, arguing that it was his “usual practice” to date physical works in a conceptual art project with the date of the project’s conception, which in the case of The Currency was 2016. Hirst and Sci…