鴻蒙5:條件-循環-列表渲染

注意:博主有個鴻蒙專欄,里面從上到下有關于鴻蒙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…