注意:博主有个鸿蒙专栏,里面从上到下有关于鸿蒙next的教学文档,大家感兴趣可以学习下

如果大家觉得博主文章写的好的话,可以点下关注,博主会一直更新鸿蒙next相关知识

专栏地址: https://blog.csdn.net/qq_56760790/category_12794123.html

文章所属类目(HarmonyOS 语言-ArkTS)

目录

1. 渲染-条件渲染

1.1 基本介绍

1.2 if/else

1.3 visibility属性控制

1.4 多种条件控制

2. 渲染-循环渲染

2.1 ForEach:循环渲染

2.1.1 基本介绍

2.1.2 语法

2.1.3 代码示例

2.1.4 key的推荐建议

3. 下拉刷新+上拉加载

3.1 下拉刷新

3.2 上拉加载


1. 渲染-条件渲染

1.1 基本介绍

在ArkTS中 我们要根据某个状态来控制元素或者组件的显示隐藏 可以采用条件渲染

  • if/else(创建销毁元素)
  • visibility属性控制

1.2 if/else

  • 支持if、else和else if语句。
  • if、else if后跟随的条件语句可以使用状态变量或者常规变量(状态变量:值的改变可以实时渲染UI,常规变量:值的改变不会实时渲染UI)。
  • 允许在容器组件内使用,通过条件渲染语句构建不同的子组件。
  • 条件渲染语句在涉及到组件的父子关系时是“透明”的,当父组件和子组件之间存在一个或多个if语句时,必须遵守父组件关于子组件使用的规则。
  • 每个分支内部的构建函数必须遵循构建函数的规则,并创建一个或多个组件。无法创建组件的空构建函数会产生语法错误。
  • 某些容器组件限制子组件的类型或数量,将条件渲染语句用于这些组件内时,这些限制将同样应用于条件渲染语句内创建的组件。例如,Grid容器组件的子组件仅支持GridItem组件,在Grid内使用条件渲染语句时,条件渲染语句内仅允许使用GridItem组件。

注意:

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

  1. 评估if和else if的状态判断条件,如果分支没有变化,无需执行以下步骤。如果分支有变化,则执行2、3步骤。
  2. 删除此前构建的所有子组件。
  3. 执行新分支的构造函数,将获取到的组件添加到if父容器中。如果缺少适用的else分支,则不构建任何内容。

@Entry
@Component
struct Demo1 {@State count: number = 0;build() {Column() {Text(`count=${this.count}`)if (this.count > 0) {Text(`count is positive`).fontColor(Color.Green)}Button('increase count').onClick(() => {this.count++;})Button('decrease count').onClick(() => {this.count--;})}}
}

显示隐藏

@Entry@Componentstruct Index {@State isShow:boolean=truebuild() {Column() {Button('显示/隐藏').width(100).height(30).onClick(()=>{if(this.isShow){this.isShow=false}else{this.isShow=true}})if(this.isShow){Text('我是东林').width(200).height(200).fontSize(40)}}.width('100%').height('100%')}}

1.3 visibility属性控制

visibility属性有以下三种:

1、Visible 显示

2、Hidden 隐藏

3、None 隐藏,但是不占位置

@Entry@Componentstruct Demo2 {@State isShow:boolean=truebuild() {Column() {Button('显示/隐藏').width(100).height(30).onClick(()=>{if(this.isShow){this.isShow=false}else{this.isShow=true}})Text('我是东林').width(200).height(200).fontSize(40).backgroundColor(Color.Green).visibility(this.isShow?Visibility.Visible:Visibility.Hidden)Text('小头').width(200).height(200).fontSize(40).backgroundColor(Color.Yellow)}.width('100%').height('100%')}}

1.4 多种条件控制

分析:

1.页面排版布局样式实现

2.下拉框的双向绑定

3.条件渲染

@Entry@ComponentV2struct Demo3 {@Local myVip: number = 0;@Local optionValue: string = '暂不开通'build() {Column({ space: 20 }) {Row() {Text('开通会员:')Select([{ value: '暂不开通' },{ value: 'VIP' },{ value: 'SVIP' }]).width('50%').selected($$this.myVip).value($$this.optionValue)// .onSelect((index, value) => {//   this.myVip = index//   this.optionValue = value// })}Row({ space: 20 }) {Image($r('app.media.img')).width(30).borderRadius(30)Text('西北吴彦祖')if (this.myVip === 0) {Text('VIP').VIPStyle(this.myVip).backgroundColor('#ccc')} else if (this.myVip === 1) {Text('VIP').VIPStyle(this.myVip).backgroundColor('#ffffb803')} else if (this.myVip === 2) {Text('SVIP').VIPStyle(this.myVip).backgroundColor('#ffb00909')}}.width('100%').justifyContent(FlexAlign.Center)}.width('100%').padding(20)}}@Extend(Text)function VIPStyle(type: number) {.padding({left: 12,right: 12,bottom: 4,top: 4}).fontColor('#fff').borderRadius(20).fontSize(12)}

2. 渲染-循环渲染

  • ForEach-最常用的
  • LazyForEach-懒加载渲染

2.1 ForEach:循环渲染

2.1.1 基本介绍

ForEach接口基于数组类型数据来进行循环渲染,需要与容器组件配合使用,且接口返回的组件应当是允许包含在ForEach父容器组件中的子组件。例如,ListItem组件要求ForEach的父容器组件必须为List组件。

2.1.2 语法

ForEach(// 数据源arr: Array,// 组件生成函数itemGenerator: (item: 单项, index?: number) => void,// 键值生成函数keyGenerator?: (item: 单项, index?: number): string => string
)

ForEach 接口基于数组类型数据来进行循环渲染,需要与容器组件配合使用。

2.1.3 代码示例

interface PayRecord {OrderName:stringOrderDate:DateOrderAmount:number
}
@Entry@ComponentV2struct ForEachDemo {PayRecordList: PayRecord[] = [{OrderName: '给老婆买口红',OrderDate: new Date('2024/05/11'),OrderAmount: 399.00},{OrderName: '给老婆买花',OrderDate: new Date('2024/05/12'),OrderAmount: 99.00},{OrderName: '给自己买手机',OrderDate: new Date('2024/05/13'),OrderAmount: 9999.00}]build() {Column() {// 标题Row() {Text('支付记录').layoutWeight(1).textAlign(TextAlign.Center).margin({left: 30})}.width('100%').padding(16).border({width: {bottom: 1},color: '#f4f5f6'})// 列表Column() {// 要循环的结构体Column({ space: 20 }) {Text('给老婆买了一朵花').fontWeight(FontWeight.Bold).width('100%')Row() {Text('¥43.00').fontColor(Color.Red)Text('2024/5/11')}.width('100%').justifyContent(FlexAlign.SpaceBetween)}.width('100%').padding(20)}.width('100%')}.width('100%').height('100%')}}

页面中生成数据,用ForEach循环

ForEach(this.PayRecordList, (item: PayRecord) => {// 要循环的结构体Column({ space: 20 }) {Text(item.OrderName).fontWeight(FontWeight.Bold).width('100%')Row() {Text(`¥${item.OrderAmount}`).fontColor(Color.Red)Text(item.OrderDate.toLocaleDateString())}.width('100%').justifyContent(FlexAlign.SpaceBetween)}.width('100%').padding(20)
})

interface PayRecord {OrderName:stringOrderDate:DateOrderAmount:number
}
@Entry
@ComponentV2
struct ForEachDemo2 {PayRecordList: PayRecord[] = [{OrderName: '给老婆买口红',OrderDate: new Date('2024/05/11'),OrderAmount: 399.00},{OrderName: '给老婆买花',OrderDate: new Date('2024/05/12'),OrderAmount: 99.00},{OrderName: '给自己买手机',OrderDate: new Date('2024/05/13'),OrderAmount: 9999.00}]build() {Column() {// 标题Row() {Text('支付记录').layoutWeight(1).textAlign(TextAlign.Center).margin({left: 30})}.width('100%').padding(16).border({width: {bottom: 1},color: '#f4f5f6'})// 列表Column() {ForEach(this.PayRecordList, (item: PayRecord) => {// 要循环的结构体Column({ space: 20 }) {Text(item.OrderName).fontWeight(FontWeight.Bold).width('100%')Row() {Text(`¥${item.OrderAmount}`).fontColor(Color.Red)Text(item.OrderDate.toLocaleDateString())}.width('100%').justifyContent(FlexAlign.SpaceBetween)}.width('100%').padding(20)})}.width('100%')}.width('100%').height('100%')}
}

2.1.4 key的推荐建议

在ForEach循环渲染过程中,系统会为每个数组元素生成一个唯一且持久的键值,用于标识对应的组件。当这个键值变化时,ArkUI框架将视为该数组元素已被替换或修改,并会基于新的键值创建一个新的组件。

ForEach提供了一个名为keyGenerator的参数,这是一个函数,开发者可以通过它自定义键值的生成规则。如果开发者没有定义keyGenerator函数,则ArkUI框架会使用默认的键值生成函数,即(item: Object, index: number) => { return index + '__' + JSON.stringify(item); }。

ForEach的第三个属性是一个回调,它是生成唯一key的

不传的话会帮助我们生成独一无二的key => index_ + JSON.stringify(item)

鸿蒙更新的原理:循环的比较-比较你的key存在不,如果存在相同的key,则不更新

只改动了某一条数据,可能所有列表都会更新

ForEach的第三个参数 宁可不给 也不要瞎给

  • 下面是key的使用案例

interface Person {id: numbername: stringage: number
}@Entry@ComponentV2struct ForEachDemo3 {@Local heroList: Person[] = [{ id: 1, name: '吕布', age: 18 },{ id: 2, name: '张飞', age: 20 },{ id: 3, name: '貂蝉', age: 21 }]build() {Column() {Button() {Text('在第1项后插入新项').fontSize(30)}.onClick(() => {this.heroList.splice(1, 0, {id: Math.random(),name: '吕蒙',age: 20});})ForEach(this.heroList, (item: Person) => {ChildItem({ item: item })})}.justifyContent(FlexAlign.Center).width('100%').height('100%').backgroundColor(0xF1F3F5)}}@ComponentV2struct ChildItem {@Param item: Person = {} as Person;aboutToAppear(): void {console.log('我被渲染了', this.item.name)}build() {Text(this.item.name + this.item.age).fontSize(30)}}

会发现使用index作为key,一旦中间项变化,后面的所有项,都需要重新渲染更新,影响性能

转而修改成以 id 作为 key,测试发现性能提升不少,只有对应项需要更新

interface Hero {id: numbername: stringage: number
}@Entry@ComponentV2struct ForEachDemo4 {@Local heroList: Hero[] = [{ id: 1, name: '吕布', age: 18 },{ id: 2, name: '张飞', age: 20 },{ id: 3, name: '貂蝉', age: 21 },]build() {Column() {Button() {Text('在第1项后插入新项').fontSize(30)}.onClick(() => {this.heroList.splice(1, 0, {id: Math.random(),name: '吕蒙',age: 20});})ForEach(this.heroList, (item: Hero) => {ChildItem({ item: item })}, (item: Hero) => item.id.toString())}.justifyContent(FlexAlign.Center).width('100%').height('100%').backgroundColor(0xF1F3F5)}}@ComponentV2struct ChildItem {@Param item: Hero = {} as Hero;aboutToAppear(): void {console.log('我被渲染了', this.item.name)}build() {Text(this.item.name + this.item.age).fontSize(30)}}

3. 下拉刷新+上拉加载

3.1 下拉刷新

Refresh组件支持下拉刷新,包裹List组件,下拉事件中更新列表

基础结构

@Entry
@ComponentV2
struct RefreshCase {@Local list: number[] = Array(20).fill(Date.now())build() {Column() {List() {ForEach(this.list, (item: number) => {ListItem() {Row() {Text(item.toString())}.width('100%').padding(20).border({width: {bottom: 1},color: Color.Gray,})}})}}.height('100%').width('100%')}
}

添加Refresh组件

@Entry
@ComponentV2
struct RefreshCase2 {@Local list: number[] = Array(20).fill(Date.now())@Local refreshing: boolean = false@BuilderrefreshContent() {Text('正在加载中...').width('100%').textAlign(TextAlign.Center)}build() {Column() {Refresh({ refreshing: $$this.refreshing, builder: this.refreshContent }) {List() {ForEach(this.list, (item: number) => {ListItem() {Row() {Text(item.toString())}.width('100%').padding(20).border({width: {bottom: 1},color: Color.Gray,})}})}}.onRefreshing(() => {setTimeout(() => {this.list = Array(20).fill(Date.now())this.refreshing = false}, 1000)})}.height('100%').width('100%')}
}

3.2 上拉加载

滚动至列表尾部(会立刻触发两次,滚动到底部+回弹一下)

import { promptAction } from '@kit.ArkUI'@Entry@ComponentV2struct RefreshCase3 {@Local list: number[] = Array(20).fill(Date.now())@Local refreshing: boolean = false@Local isLoading: boolean = false // 标记是否正在加载中scroller: Scroller = new Scroller()@BuilderrefreshContent() {Text('正在加载中...').width('100%').textAlign(TextAlign.Center)}build() {Column() {Refresh({refreshing: $$this.refreshing,builder: this.refreshContent}) {List({ scroller: this.scroller }) {ForEach(this.list, (item: number) => {ListItem() {Row() {Text(item.toString())}.width('100%').padding(20).border({width: {bottom: 1},color: Color.Gray,})}})if (this.isLoading) {ListItem() {Text('正在拼命加载中...').width('100%').textAlign(TextAlign.Center).height(80)}}}.onReachEnd(() => {if (!this.isLoading) {this.isLoading = true // 开始加载, 显示Loading动画this.scroller.scrollEdge(Edge.End)setTimeout(() => {this.list.push(...Array(10).fill(Date.now()))promptAction.showToast({message: '10条数据添加成功'})this.isLoading = false}, 2000)}})}.onRefreshing(() => {setTimeout(() => {this.list = Array(20).fill(Date.now())this.refreshing = false}, 1000)})}.height('100%').width('100%')}}

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

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

相关文章

浅谈AI大模型-MCP

MCP简介 MCP(Model Context Protocol,模型上下文协议 ),24年11月初的时候Anthropic发了一篇技术博客,推出了他们的模型上下文协议MCP,介绍了一种规范:应用如何为LLM提供上下文。官网称MCP为AI应…

MySQL数据库基础概述

前言: MySQL作为全球应用最广泛的开源关系型数据库管理系统(RDBMS)​,凭借其高性能、高可靠性与零成本特性,已成为Web应用、企业系统的核心数据引擎。它遵循SQL标准,通过表结构实现数据的结构化存储&#x…

桌面小屏幕实战课程:DesktopScreen 16 HTTP

飞书文档http://https://x509p6c8to.feishu.cn/docx/doxcnrxBs55qGn6xoysTcJpqwRf /home/kemp/work/esp/esp-idf/examples/protocols/http_request 源码下载方式参考: 源码下载方式 心知天气 注册账号,申请产品,获取密钥 产品 天气数据 H…

vs2019 + QT下 vs2019创建的项目打开ui文件失败

问题: 在vs2019 QT模式下。使用2019创建工程后。点击ui文件打开时。出现奔溃,如下图 解决方式: ui文件->右键->打开方式->添加->程序->点击三个点->qcreator(qt安装目录) ->设置为默认值->确定 点击设置为默认值,点…

WPS之PPT镂空效果实现

1、准备一张图片,剪切存入剪贴板 2、把图片设为背景 右键 》 设置背景格式 》 图片或纹理填充 》 图片填充选择剪贴板 3、插入一个矩形覆盖全图,设置无线条渐变填充从左到右 4、插入圆角矩形 5、单击小黄点调整弧度 6、选择无线条幻灯片背景填充 7、插…

服务注册中心的本质抉择:从业务本质看AP与CP的终极之选

本文从服务注册中心的本质职责出发,通过分析其核心功能、业务场景和技术约束,深入探讨服务注册中心在架构设计上应该优先保证AP还是CP特性。文章首先剖析服务注册中心的根本使命,然后从分布式系统原理、生产实践案例和性能表现三个维度进行对…

mybatis-plus从入门到入土(一):快速开始

​ 朋友们, 大家好, 从今天开始我想开一个系列博客。名字起的比较随意就叫Mybatis-Plus从入门到入土, 这系列博客的定位是从基础使用开始, 然后逐步深入全面的了解Mybatis-Plus框架, 写这个博客的主要原因是工作中经常用到Mybatis-Plus框架, 因而对这个框架相对比较了解一些, 顺…

如何快速将iPhone中的文本保存到电脑上

您的 iPhone 上是否有很多重要的短信,并且您想将短信备份到计算机上?我们都知道传输消息与传输照片不同,但幸运的是,您可以使用相关的工具和方法来实现。我们介绍了 4 种方法来解释如何将 iPhone 中的文本保存到计算机。所有的办法…

【OpenGL学习】(八)图形变换

OpenGL图形变换介绍:https://learnopengl-cn.github.io/01%20Getting%20started/07%20Transformations 【OpenGL学习】(八)图形变换 本项目将通过变换矩阵,对【OpenGL学习】(七)纹理单元 中的图形进行缩放…

从理论到实战:解密大型语言模型的核心技术与应用指南

一、Transformer:语言理解与生成的基石 Transformer 架构的出现,彻底改变了自然语言处理(NLP)的格局。它以“注意力”为核心,将全局依赖的捕捉效率推向新高。下面用 图简要概览其数据流: 从上图可见&#…

kali换源

在Kali Linux中切换软件源可以提高软件下载速度,下面为你介绍切换源的方法。 一、备份原配置文件 首先备份原配置文件,避免操作失误导致问题: sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak二、编辑源配置文件 使用以下命令编…

从决策树到随机森林:Python机器学习里的“树形家族“深度实战与原理拆解

引言 在机器学习的算法森林中,有一对"树形兄弟"始终占据着C位——决策树像个逻辑清晰的"老教授",用可视化的树状结构把复杂决策过程拆解成"是/否"的简单判断;而它的进阶版随机森林更像一支"精英军团&quo…

uniapp,每次请求时,中断上次请求

1.封装uni.request import {BASE_URL} from "/config/config.js"import store from "/store/index.js"; class RequestManager {constructor() {this.requestTasks new Map() // 存储所有请求任务this.baseURL BASE_URLthis.header {Content-Type: app…

DuDuTalk | 武汉赛思云科技有限公司通过武汉市人工智能企业认定!

近日,2025年武汉市人工智能企业名单正式公布!武汉赛思云科技有限公司(以下简称赛思云科技)凭借卓越的技术实力与创新成果,成功入选武汉市人工智能企业。这是对公司长期深耕AI语音智能领域、推动数字化转型的高度认可&a…

STM32实现傅里叶变换精确计算采样电流值

以下是基于离散傅里叶变换(DFT)算法在单片机上实现精确电流值计算的全流程指南,结合硬件选型、算法优化、代码实现及实际应用场景分析,综合多篇技术文档的实践要点: ⚙️ 一、系统设计核心要点 硬件选型与配置 单片机选择:优先采用带硬件浮点单元(FPU)的STM32F4/F7系列…

python 爬虫 下载视频

测试 OK II 在开发者工具里面 直接搜索m3u8 可以直接找相对应连接地址继续分析 这个m3u8 url地址是从哪里过来的 在什么地方有 III 我们想要视频数据 <m3u8连接> 在 网页源代码里面有获取整个视频内容 --》分为N个视频片段《ts文件》-->在m3u8连接里面--> 视频播放…

希尔伯特空间:无穷维度的几何世界

希尔伯特空间&#xff1a;无穷维度的几何世界 从量子物理到信号处理&#xff0c;希尔伯特空间为现代科学与工程提供了强大的数学框架 引言&#xff1a;无限维度的舞台 在数学和物理学的广阔领域中&#xff0c;希尔伯特空间扮演着至关重要的角色。这个完备的内积空间不仅推广了…

Transformer结构与代码实现详解

参考&#xff1a; Transformer模型详解&#xff08;图解最完整版&#xff09; - 知乎https://zhuanlan.zhihu.com/p/338817680GitHub - liaoyanqing666/transformer_pytorch: 完整的原版transformer程序&#xff0c;complete origin transformer programhttps://github.com/lia…

Adobe InDesign 2025

Adobe InDesign 2025(ID2025)桌面出版软件和在线发布工具,报刊杂志印刷排版设计软件。Adobe InDesign中文版主要用于传单设计,海报设计,明信片设计,电子书设计,排版,手册设计,数字杂志,iPad应用程序和在线交互文档。它是首款支持Unicode文本处理的主流DTP应用程序,率先使用新型…

Linux下获取指定时间内某个进程的平均CPU使用率

一、引言 通过pidstat工具可以测量某个进程在两个时间点之间的平均CPU利用率。 二、pidstat工具的安装 pidstat属于sysstat套件的一部分。以Ubuntu系统为例&#xff0c;执行下面命令下载安装sysstat套件&#xff1a; apt-get install sysstat 执行完后&#xff0c;终端执行p…