国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

中國建設(shè)教育協(xié)會(huì)官方網(wǎng)站查百度搜索指數(shù)入口

中國建設(shè)教育協(xié)會(huì)官方網(wǎng)站查,百度搜索指數(shù)入口,wordpress 移動(dòng)端 搜索,企業(yè)網(wǎng)站的建設(shè)目的目錄 1、接口說明 2、鍵值生成規(guī)則 3、組件創(chuàng)建規(guī)則 3.1、首次渲染 3.2、非首次渲染 4、使用場(chǎng)景 4.1、數(shù)據(jù)源不變 4.2、數(shù)據(jù)源組項(xiàng)發(fā)生變化 4.3、數(shù)據(jù)源數(shù)組項(xiàng)子屬性變化 5、反例 5.1、渲染結(jié)果非預(yù)期 5.2、渲染性能降低 Android開發(fā)中我們有ListView組件、GridVi…

? ? ? ?

目錄

1、接口說明

2、鍵值生成規(guī)則

3、組件創(chuàng)建規(guī)則

3.1、首次渲染

3.2、非首次渲染

4、使用場(chǎng)景

4.1、數(shù)據(jù)源不變

4.2、數(shù)據(jù)源組項(xiàng)發(fā)生變化

?4.3、數(shù)據(jù)源數(shù)組項(xiàng)子屬性變化

5、反例?

5.1、渲染結(jié)果非預(yù)期

5.2、渲染性能降低


Android開發(fā)中我們有ListView組件、GridView組件、RecyclerView組件,這些組件可以為我們創(chuàng)建一個(gè)列表;在鴻蒙開發(fā)中,則不一樣,它沒有類似Android中的組件,但是卻提供了循環(huán)渲染機(jī)制ForEach接口幫助我們渲染一個(gè)列表,本節(jié)主要介紹該主題。

????????ForEach接口基于數(shù)組類型數(shù)據(jù)來進(jìn)行循環(huán)渲染,需要與容器組件配合使用,且接口返回的組件應(yīng)當(dāng)是允許包含在ForEach父容器組件中的子組件。例如,ListItem組件要求ForEach的父容器組件必須為List組件。

1、接口說明

? ? ? ? ForEach接口定義如下:

ForEach(arr: Array,itemGenerator: (item: any, index?: number) => void,keyGenerator?: (item: any, index?: number): string => string
)
  • arr?

    數(shù)據(jù)源,為Array類型的數(shù)組。

    說明

    - 可以設(shè)置為空數(shù)組,此時(shí)不會(huì)創(chuàng)建子組件。

    - 可以設(shè)置返回值為數(shù)組類型的函數(shù),例如arr.slice(1, 3),但設(shè)置的函數(shù)不應(yīng)改變包括數(shù)組本身在內(nèi)的任何狀態(tài)變量,例如不應(yīng)使用Array.splice(),Array.sort()或Array.reverse()這些會(huì)改變?cè)瓟?shù)組的函數(shù)。

  • itemGenerator

    組件生成函數(shù)。

    - 為數(shù)組中的每個(gè)元素創(chuàng)建對(duì)應(yīng)的組件。

    - item參數(shù):arr數(shù)組中的數(shù)據(jù)項(xiàng)。

    - index參數(shù)(可選):arr數(shù)組中的數(shù)據(jù)項(xiàng)索引。

    說明

    - 組件的類型必須是ForEach的父容器所允許的。例如,ListItem組件要求ForEach的父容器組件必須為List組件。

  • ForEach的itemGenerator函數(shù)可以包含if/else條件渲染邏輯。另外,也可以在if/else條件渲染語句中使用ForEach組件。
  • 在初始化渲染時(shí),ForEach會(huì)加載數(shù)據(jù)源的所有數(shù)據(jù),并為每個(gè)數(shù)據(jù)項(xiàng)創(chuàng)建對(duì)應(yīng)的組件,然后將其掛載到渲染樹上。如果數(shù)據(jù)源非常大或有特定的性能需求,建議使用LazyForEach組件。

2、鍵值生成規(guī)則

????????在ForEach循環(huán)渲染過程中,系統(tǒng)會(huì)為每個(gè)數(shù)組元素生成一個(gè)唯一且持久的鍵值,用于標(biāo)識(shí)對(duì)應(yīng)的組件。當(dāng)這個(gè)鍵值變化時(shí),ArkUI框架將視為該數(shù)組元素已被替換或修改,并會(huì)基于新的鍵值創(chuàng)建一個(gè)新的組件。

????????ForEach提供了一個(gè)名為keyGenerator的參數(shù),這是一個(gè)函數(shù),開發(fā)者可以通過它自定義鍵值的生成規(guī)則。如果開發(fā)者沒有定義keyGenerator函數(shù),則ArkUI框架會(huì)使用默認(rèn)的鍵值生成函數(shù),即(item: any, index: number) => { return index + '__' + JSON.stringify(item); }。

????????ArkUI框架對(duì)于ForEach的鍵值生成有一套特定的判斷規(guī)則,這主要與itemGenerator函數(shù)的第二個(gè)參數(shù)index以及keyGenerator函數(shù)的返回值有關(guān)??偟膩碚f,只有當(dāng)開發(fā)者在itemGenerator函數(shù)中聲明了index參數(shù),并且自定義的keyGenerator函數(shù)返回值中不包含index參數(shù)時(shí),ArkUI框架才會(huì)在開發(fā)者自定義的keyGenerator函數(shù)返回值前添加index參數(shù),作為最終的鍵值。在其他情況下,系統(tǒng)將直接使用開發(fā)者自定義的keyGenerator函數(shù)返回值作為最終的鍵值。如果keyGenerator函數(shù)未定義,系統(tǒng)將使用上述默認(rèn)的鍵值生成函數(shù)。具體的鍵值生成規(guī)則判斷邏輯如下圖所示。

ArkUI框架會(huì)對(duì)重復(fù)的鍵值發(fā)出警告。在UI更新的場(chǎng)景下,如果出現(xiàn)重復(fù)的鍵值,框架可能無法正常工作,具體請(qǐng)參見渲染結(jié)果非預(yù)期?

3、組件創(chuàng)建規(guī)則

????????在確定鍵值生成規(guī)則后,ForEach的第二個(gè)參數(shù)itemGenerator函數(shù)會(huì)根據(jù)鍵值生成規(guī)則為數(shù)據(jù)源的每個(gè)數(shù)組項(xiàng)創(chuàng)建組件。組件的創(chuàng)建包括兩種情況:Foreach首次渲染和Foreach非首次渲染。

3.1、首次渲染

????????在ForEach首次渲染時(shí),會(huì)根據(jù)前述鍵值生成規(guī)則為數(shù)據(jù)源的每個(gè)數(shù)組項(xiàng)生成唯一鍵值,并創(chuàng)建相應(yīng)的組件。

@Entry
@Component
struct ForeachRenderDemo1Page {@State simpleList: Array<string> = ['one', 'two', 'three'];build() {Row() {Column() {ForEach(this.simpleList, (item: string) => {ForeachDemo1ChildItem({ item: item })}, (item: string) => item)}.width('100%').height('100%')}.height('100%').backgroundColor(0xF1F3F5)}
}@Component
struct ForeachDemo1ChildItem {@Prop item: string;build() {Text(this.item).fontSize(50)}
}

? ? ? ? 運(yùn)行結(jié)果如下:


ForEach數(shù)據(jù)源不存在相同值案例首次渲染運(yùn)行效果圖

????????在上述代碼中,鍵值生成規(guī)則是keyGenerator函數(shù)的返回值item。在ForEach渲染循環(huán)時(shí),為數(shù)據(jù)源數(shù)組項(xiàng)依次生成鍵值one、two和three,并創(chuàng)建對(duì)應(yīng)的ChildItem組件渲染到界面上。

????????當(dāng)不同數(shù)組項(xiàng)按照鍵值生成規(guī)則生成的鍵值相同時(shí),框架的行為是未定義的。例如,在以下代碼中,ForEach渲染相同的數(shù)據(jù)項(xiàng)two時(shí),只創(chuàng)建了一個(gè)ChildItem組件,而沒有創(chuàng)建多個(gè)具有相同鍵值的組件。

@Entry
@Component
struct ForeachRenderDemo2Page {@State simpleList: Array<string> = ['one', 'two', 'two', 'three'];build() {Row() {Column() {ForEach(this.simpleList, (item: string) => {ForeachRenderDemo2ChildItem({ item: item })}, (item: string) => item)}.width('100%').height('100%')}.height('100%')}
}@Component
struct ForeachRenderDemo2ChildItem {@Prop item: string;build() {Text(this.item).fontSize(50)}
}

? ? ? ? 運(yùn)行結(jié)果如下:

數(shù)據(jù)源存在相同值案例首次渲染

????????在該示例中,最終鍵值生成規(guī)則為item。當(dāng)ForEach遍歷數(shù)據(jù)源simpleList,遍歷到索引為1的two時(shí),按照最終鍵值生成規(guī)則生成鍵值為two的組件并進(jìn)行標(biāo)記。當(dāng)遍歷到索引為2的two時(shí),按照最終鍵值生成規(guī)則當(dāng)前項(xiàng)的鍵值也為two,此時(shí)不再創(chuàng)建新的組件。

3.2、非首次渲染

????????在ForEach組件進(jìn)行非首次渲染時(shí),它會(huì)檢查新生成的鍵值是否在上次渲染中已經(jīng)存在。如果鍵值不存在,則會(huì)創(chuàng)建一個(gè)新的組件;如果鍵值存在,則不會(huì)創(chuàng)建新的組件,而是直接渲染該鍵值所對(duì)應(yīng)的組件。例如,在以下的代碼示例中,通過點(diǎn)擊事件修改了數(shù)組的第三項(xiàng)值為"new three",這將觸發(fā)ForEach組件進(jìn)行非首次渲染。?

@Entry
@Component
struct ForeachRenderDemo3Page {@State simpleList: Array<string> = ['one', 'two', 'three'];build() {Row() {Column() {Text('點(diǎn)擊修改第3個(gè)數(shù)組項(xiàng)的值').fontSize(24).fontColor(Color.Red).onClick(() => {this.simpleList[2] = 'new three';})ForEach(this.simpleList, (item: string) => {ForeachRenderDemo3ChildItem({ item: item }).margin({ top: 20 })}, (item: string) => item)}.justifyContent(FlexAlign.Center).width('100%').height('100%')}.height('100%')}
}@Component
struct ForeachRenderDemo3ChildItem {@Prop item: string;build() {Text(this.item).fontSize(30)}
}

????????運(yùn)行效果如下圖:

????????從本例可以看出@State 能夠監(jiān)聽到簡單數(shù)據(jù)類型數(shù)組數(shù)據(jù)源 simpleList 數(shù)組項(xiàng)的變化。

  1. 當(dāng) simpleList 數(shù)組項(xiàng)發(fā)生變化時(shí),會(huì)觸發(fā) ForEach 進(jìn)行重新渲染。
  2. ForEach 遍歷新的數(shù)據(jù)源 ['one', 'two', 'new three'],并生成對(duì)應(yīng)的鍵值one、two和new three。
  3. 其中,鍵值one和two在上次渲染中已經(jīng)存在,所以 ForEach 復(fù)用了對(duì)應(yīng)的組件并進(jìn)行了渲染。對(duì)于第三個(gè)數(shù)組項(xiàng) "new three",由于其通過鍵值生成規(guī)則 item 生成的鍵值new three在上次渲染中不存在,因此 ForEach 為該數(shù)組項(xiàng)創(chuàng)建了一個(gè)新的組件。

4、使用場(chǎng)景

????????ForEach組件在開發(fā)過程中的主要應(yīng)用場(chǎng)景包括:數(shù)據(jù)源不變、數(shù)據(jù)源數(shù)組項(xiàng)發(fā)生變化(如插入、刪除操作)、數(shù)據(jù)源數(shù)組項(xiàng)子屬性變化。

4.1、數(shù)據(jù)源不變

????????在數(shù)據(jù)源保持不變的場(chǎng)景中,數(shù)據(jù)源可以直接采用基本數(shù)據(jù)類型。例如,在頁面加載狀態(tài)時(shí),可以使用骨架屏列表進(jìn)行渲染展示。

@Entry
@Component
struct ForeachRenderDemo4Page {@State simpleList: Array<number> = [1, 2, 3, 4, 5];build() {Column() {ForEach(this.simpleList, (item: string) => {ArticleSkeletonView().margin({ top: 20 })}, (item: string) => item)}.padding(20).width('100%').height('100%')}
}@Builder
function textArea(width: number | Resource | string = '100%', height: number | Resource | string = '100%') {Row().width(width).height(height).backgroundColor('#FFF2F3F4')
}@Component
struct ArticleSkeletonView {build() {Row() {Column() {textArea(80, 80)}.margin({ right: 20 })Column() {textArea('60%', 20)textArea('50%', 20)}.alignItems(HorizontalAlign.Start).justifyContent(FlexAlign.SpaceAround).height('100%')}.padding(20).borderRadius(12).backgroundColor('#FFECECEC').height(120).width('100%').justifyContent(FlexAlign.SpaceBetween)}
}

運(yùn)行結(jié)果如下:

????????在本示例中,采用數(shù)據(jù)項(xiàng)item作為鍵值生成規(guī)則,由于數(shù)據(jù)源simpleList的數(shù)組項(xiàng)各不相同,因此能夠保證鍵值的唯一性。?

4.2、數(shù)據(jù)源組項(xiàng)發(fā)生變化

????????在數(shù)據(jù)源數(shù)組項(xiàng)發(fā)生變化的場(chǎng)景下,例如進(jìn)行數(shù)組插入、刪除操作或者數(shù)組項(xiàng)索引位置發(fā)生交換時(shí),數(shù)據(jù)源應(yīng)為對(duì)象數(shù)組類型,并使用對(duì)象的唯一ID作為最終鍵值。例如,當(dāng)在頁面上通過手勢(shì)上滑加載下一頁數(shù)據(jù)時(shí),會(huì)在數(shù)據(jù)源數(shù)組尾部新增新獲取的數(shù)據(jù)項(xiàng),從而使得數(shù)據(jù)源數(shù)組長度增大。

import { Article } from './bean/Article';@Entry
@Component
struct ForeachRenderDemo5Page {@State isListReachEnd: boolean = false;@State articleList: Array<Article> = [new Article('001', '第1篇文章', '文章簡介內(nèi)容'),new Article('002', '第2篇文章', '文章簡介內(nèi)容'),new Article('003', '第3篇文章', '文章簡介內(nèi)容'),new Article('004', '第4篇文章', '文章簡介內(nèi)容'),new Article('005', '第5篇文章', '文章簡介內(nèi)容'),new Article('006', '第6篇文章', '文章簡介內(nèi)容'),new Article('007', '第7篇文章', '文章簡介內(nèi)容'),new Article('008', '第8篇文章', '文章簡介內(nèi)容'),new Article('009', '第9篇文章', '文章簡介內(nèi)容'),new Article('010', '第10篇文章', '文章簡介內(nèi)容')]private count: number = 11;loadMoreArticles() {console.log('loadMoreArticles')this.articleList.push(new Article(`0${++this.count}`, `加載的第${this.count}篇新文章`, `第${this.count}篇文章簡介內(nèi)容`));}build() {Column({ space: 5 }) {List() {ForEach(this.articleList, (item: Article) => {ListItem() {ForeachRenderDemo5ArticleCard({ article: item }).margin({ top: 20 })}}, (item: Article) => item.id)}.onReachEnd(() => {console.log('onReachEnd')this.isListReachEnd = true;}).parallelGesture(PanGesture({ direction: PanDirection.Up, distance: 80 }).onActionStart(() => {console.log('onActionStart')if (this.isListReachEnd) {this.loadMoreArticles();this.isListReachEnd = false;}})).padding(20).scrollBar(BarState.Off).height('100%').height('100%')}.width('100%').height('100%').backgroundColor(0xF1F3F5)}
}@Component
struct ForeachRenderDemo5ArticleCard {@Prop article: Article;build() {Row() {Image($r('app.media.icon')).width(80).height(80).margin({ right: 20 })Column() {Text(this.article.title).fontSize(20).margin({ bottom: 8 })Text(this.article.brief).fontSize(16).fontColor(Color.Gray).margin({ bottom: 8 })}.alignItems(HorizontalAlign.Start).width('80%').height('100%')}.padding(20).borderRadius(12).backgroundColor('#FFECECEC').height(120).width('100%').justifyContent(FlexAlign.SpaceBetween)}
}
運(yùn)行結(jié)果如下:

????????在本示例中,ArticleCard組件作為ArticleListView組件的子組件,通過@Prop裝飾器接收一個(gè)Article對(duì)象,用于渲染文章卡片。

  1. 當(dāng)列表滾動(dòng)到底部時(shí),如果手勢(shì)滑動(dòng)距離超過指定的80,將觸發(fā)loadMoreArticle()函數(shù)。此函數(shù)會(huì)在articleList數(shù)據(jù)源的尾部添加一個(gè)新的數(shù)據(jù)項(xiàng),從而增加數(shù)據(jù)源的長度。
  2. 數(shù)據(jù)源被@State裝飾器修飾,ArkUI框架能夠感知到數(shù)據(jù)源長度的變化,并觸發(fā)ForEach進(jìn)行重新渲染
?4.3、數(shù)據(jù)源數(shù)組項(xiàng)子屬性變化

????????當(dāng)數(shù)據(jù)源的數(shù)組項(xiàng)為對(duì)象數(shù)據(jù)類型,并且只修改某個(gè)數(shù)組項(xiàng)的屬性值時(shí),由于數(shù)據(jù)源為復(fù)雜數(shù)據(jù)類型,ArkUI框架無法監(jiān)聽到@State裝飾器修飾的數(shù)據(jù)源數(shù)組項(xiàng)的屬性變化,從而無法觸發(fā)ForEach的重新渲染。為實(shí)現(xiàn)ForEach重新渲染,需要結(jié)合@Observed和@ObjectLink裝飾器使用。例如,在文章列表卡片上點(diǎn)擊“點(diǎn)贊”按鈕,從而修改文章的點(diǎn)贊數(shù)量。

import { Article } from './bean/Article';@Entry
@Component
struct ForeachRenderDemo6Page {@State articleList: Array<Article> = [new Article('001', '第0篇文章', '文章簡介內(nèi)容'),new Article('002', '第1篇文章', '文章簡介內(nèi)容'),new Article('003', '第2篇文章', '文章簡介內(nèi)容'),new Article('004', '第4篇文章', '文章簡介內(nèi)容'),new Article('005', '第5篇文章', '文章簡介內(nèi)容'),new Article('006', '第6篇文章', '文章簡介內(nèi)容'),];build() {List() {ForEach(this.articleList, (item: Article) => {ListItem() {ForeachRenderDemo6ArticleCard({article: item}).margin({ top: 20 })}}, (item: Article) => item.id)}.padding(20).scrollBar(BarState.Off).backgroundColor(0xF1F3F5)}
}@Component
struct ForeachRenderDemo6ArticleCard {@ObjectLink article: Article;handleLiked() {this.article.isLiked = !this.article.isLiked;this.article.likesCount = this.article.isLiked ? this.article.likesCount + 1 : this.article.likesCount - 1;}build() {Row() {Image($r('app.media.icon')).width(80).height(80).margin({ right: 20 })Column() {Text(this.article.title).fontSize(20).margin({ bottom: 8 })Text(this.article.brief).fontSize(16).fontColor(Color.Gray).margin({ bottom: 8 })Row() {Image(this.article.isLiked ? $r('app.media.icon_approve_checked') : $r('app.media.icon_approve_normal')).width(24).height(24).margin({ right: 8 })Text(this.article.likesCount.toString()).fontSize(16)}.onClick(() => this.handleLiked()).justifyContent(FlexAlign.Center)}.alignItems(HorizontalAlign.Start).width('80%').height('100%')}.padding(20).borderRadius(12).backgroundColor('#FFECECEC').height(120).width('100%').justifyContent(FlexAlign.SpaceBetween)}
}
運(yùn)行結(jié)果如下:

????????在本示例中,Article類被@Observed裝飾器修飾。父組件ArticleListView傳入Article對(duì)象實(shí)例給子組件ArticleCard,子組件使用@ObjectLink裝飾器接收該實(shí)例。

  1. 當(dāng)點(diǎn)擊第1個(gè)文章卡片上的點(diǎn)贊圖標(biāo)時(shí),會(huì)觸發(fā)ArticleCard組件的handleLiked函數(shù)。該函數(shù)修改第1個(gè)卡片對(duì)應(yīng)組件里article實(shí)例的isLiked和likesCount屬性值。
  2. 由于子組件ArticleCard中的article使用了@ObjectLink裝飾器,父子組件共享同一份article數(shù)據(jù)。因此,父組件中articleList的第1個(gè)數(shù)組項(xiàng)的isLiked和likedCounts數(shù)值也會(huì)同步修改。
  3. 當(dāng)父組件監(jiān)聽到數(shù)據(jù)源數(shù)組項(xiàng)屬性值變化時(shí),會(huì)觸發(fā)ForEach重新渲染。
  4. 在此處,ForEach鍵值生成規(guī)則為數(shù)組項(xiàng)的id屬性值。當(dāng)ForEach遍歷新數(shù)據(jù)源時(shí),數(shù)組項(xiàng)的id均沒有變化,不會(huì)新建組件。
  5. 渲染第1個(gè)數(shù)組項(xiàng)對(duì)應(yīng)的ArticleCard組件時(shí),讀取到的isLiked和likesCount為修改后的新值。
  • 盡量避免在最終的鍵值生成規(guī)則中包含數(shù)據(jù)項(xiàng)索引index,以防止出現(xiàn)渲染結(jié)果非預(yù)期和渲染性能降低。如果業(yè)務(wù)確實(shí)需要使用index,例如列表需要通過index進(jìn)行條件渲染,開發(fā)者需要接受ForEach在改變數(shù)據(jù)源后重新創(chuàng)建組件所帶來的性能損耗。
  • 為滿足鍵值的唯一性,對(duì)于對(duì)象數(shù)據(jù)類型,建議使用對(duì)象數(shù)據(jù)中的唯一id作為鍵值。
  • 基本數(shù)據(jù)類型的數(shù)據(jù)項(xiàng)沒有唯一ID屬性。如果使用基本數(shù)據(jù)類型本身作為鍵值,必須確保數(shù)組項(xiàng)無重復(fù)。因此,對(duì)于數(shù)據(jù)源會(huì)發(fā)生變化的場(chǎng)景,建議將基本數(shù)據(jù)類型數(shù)組轉(zhuǎn)化為具備唯一ID屬性的對(duì)象數(shù)據(jù)類型數(shù)組,再使用ID屬性作為鍵值生成規(guī)則。

5、反例?

????????開發(fā)者在使用ForEach的過程中,若對(duì)于鍵值生成規(guī)則的理解不夠充分,可能會(huì)出現(xiàn)錯(cuò)誤的使用方式。錯(cuò)誤使用一方面會(huì)導(dǎo)致功能層面問題,例如渲染結(jié)果非預(yù)期,另一方面會(huì)導(dǎo)致性能層面問題,例如渲染性能降低。

5.1、渲染結(jié)果非預(yù)期

????????在本示例中,通過設(shè)置ForEach的第三個(gè)參數(shù)KeyGenerator函數(shù),自定義鍵值生成規(guī)則為數(shù)據(jù)源的索引index的字符串類型值。當(dāng)點(diǎn)擊父組件Parent中“在第1項(xiàng)后插入新項(xiàng)”文本組件后,界面會(huì)出現(xiàn)非預(yù)期的結(jié)果。

@Entry
@Component
struct ForeachRenderDemo7Page {@State simpleList: Array<string> = ['one', 'two', 'three'];build() {Column() {Button() {Text('在第1項(xiàng)后插入新項(xiàng)').fontSize(30)}.onClick(() => {this.simpleList.splice(1, 0, 'new item');})ForEach(this.simpleList, (item: string) => {ChildItem({ item: item })}, (item: string, index: number) => index.toString())}.justifyContent(FlexAlign.Center).width('100%').height('100%')}
}@Component
struct ChildItem {@Prop item: string;build() {Text(this.item).fontSize(30)}
}

運(yùn)行結(jié)果如下:

????????ForEach在首次渲染時(shí),創(chuàng)建的鍵值依次為"0"、"1"、"2"。

????????插入新項(xiàng)后,數(shù)據(jù)源simpleList變?yōu)閇'one', 'new item', 'two', 'three'],框架監(jiān)聽到@State裝飾的數(shù)據(jù)源長度變化觸發(fā)ForEach重新渲染。

????????ForEach依次遍歷新數(shù)據(jù)源,遍歷數(shù)據(jù)項(xiàng)"one"時(shí)生成鍵值"0",存在相同鍵值,因此不創(chuàng)建新組件。繼續(xù)遍歷數(shù)據(jù)項(xiàng)"new item"時(shí)生成鍵值"1",存在相同鍵值,因此不創(chuàng)建新組件。繼續(xù)遍歷數(shù)據(jù)項(xiàng)"two"生成鍵值"2",存在相同鍵值,因此不創(chuàng)建新組件。最后遍歷數(shù)據(jù)項(xiàng)"three"時(shí)生成鍵值"3",不存在相同鍵值,創(chuàng)建內(nèi)容為"three"的新組件并渲染。

????????從以上可以看出,當(dāng)最終鍵值生成規(guī)則包含index時(shí),期望的界面渲染結(jié)果為['one', 'new item', 'two', 'three'],而實(shí)際的渲染結(jié)果為['one', 'two', 'three', 'three'],渲染結(jié)果不符合開發(fā)者預(yù)期。因此,開發(fā)者在使用ForEach時(shí)應(yīng)盡量避免最終鍵值生成規(guī)則中包含index。

5.2、渲染性能降低

在本示例中,ForEach的第三個(gè)參數(shù)KeyGenerator函數(shù)處于缺省狀態(tài)。根據(jù)上述鍵值生成規(guī)則,此例使用框架默認(rèn)的鍵值生成規(guī)則,即最終鍵值為字符串index + '__' + JSON.stringify(item)。當(dāng)點(diǎn)擊“在第1項(xiàng)后插入新項(xiàng)”文本組件后,ForEach將需要為第2個(gè)數(shù)組項(xiàng)以及其后的所有項(xiàng)重新創(chuàng)建組件。

@Entry
@Component
struct ForeachRenderDemo8Page {@State simpleList: Array<string> = ['one', 'two', 'three'];build() {Column() {Button() {Text('在第1項(xiàng)后插入新項(xiàng)').fontSize(30)}.onClick(() => {this.simpleList.splice(1, 0, 'new item');console.log(`[onClick]: simpleList is ${JSON.stringify(this.simpleList)}`);})ForEach(this.simpleList, (item: string) => {ForeachRenderDemo8ChildItem({ item: item })})}.justifyContent(FlexAlign.Center).width('100%').height('100%').backgroundColor(0xF1F3F5)}
}@Component
struct ForeachRenderDemo8ChildItem {@Prop item: string;aboutToAppear() {console.log(`[aboutToAppear]: item is ${this.item}`);}build() {Text(this.item).fontSize(50)}
}

? ? ? ? ?運(yùn)行結(jié)果如下:

? ? ? ? ?點(diǎn)擊插入新項(xiàng),ide打印如下日志:

????????插入新項(xiàng)后,ForEach為new item、 two、 three三個(gè)數(shù)組項(xiàng)創(chuàng)建了對(duì)應(yīng)的組件ChildItem,并執(zhí)行了組件的aboutToAppear()生命周期函數(shù)。這是因?yàn)?#xff1a;

  1. 在ForEach首次渲染時(shí),創(chuàng)建的鍵值依次為0__one、1__two、2__three。
  2. 插入新項(xiàng)后,數(shù)據(jù)源simpleList變?yōu)閇'one', 'new item', 'two', 'three'],ArkUI框架監(jiān)聽到@State裝飾的數(shù)據(jù)源長度變化觸發(fā)ForEach重新渲染。
  3. ForEach依次遍歷新數(shù)據(jù)源,遍歷數(shù)據(jù)項(xiàng)one時(shí)生成鍵值0__one,鍵值已存在,因此不創(chuàng)建新組件。繼續(xù)遍歷數(shù)據(jù)項(xiàng)new item時(shí)生成鍵值1__new item,不存在相同鍵值,創(chuàng)建內(nèi)容為new item的新組件并渲染。繼續(xù)遍歷數(shù)據(jù)項(xiàng)two生成鍵值2__two,不存在相同鍵值,創(chuàng)建內(nèi)容為two的新組件并渲染。最后遍歷數(shù)據(jù)項(xiàng)three時(shí)生成鍵值3__three,不存在相同鍵值,創(chuàng)建內(nèi)容為three的新組件并渲染。

????????盡管此示例中界面渲染的結(jié)果符合預(yù)期,但每次插入一條新數(shù)組項(xiàng)時(shí),ForEach都會(huì)為從該數(shù)組項(xiàng)起后面的所有數(shù)組項(xiàng)全部重新創(chuàng)建組件。當(dāng)數(shù)據(jù)源數(shù)據(jù)量較大或組件結(jié)構(gòu)復(fù)雜時(shí),由于組件無法得到復(fù)用,將導(dǎo)致性能體驗(yàn)不佳。因此,除非必要,否則不推薦將第三個(gè)參數(shù)KeyGenerator函數(shù)處于缺省狀態(tài),以及在鍵值生成規(guī)則中包含數(shù)據(jù)項(xiàng)索引index。

http://aloenet.com.cn/news/39192.html

相關(guān)文章:

  • 做個(gè)商城網(wǎng)站要多少錢農(nóng)產(chǎn)品營銷方案
  • 中國企業(yè)500強(qiáng)厲害嗎電腦優(yōu)化軟件推薦
  • 免費(fèi)名字設(shè)計(jì)logo網(wǎng)站查網(wǎng)站
  • 做淘寶客網(wǎng)站要備案嗎營銷網(wǎng)站建設(shè)都是專業(yè)技術(shù)人員
  • 個(gè)人網(wǎng)站建設(shè)策劃書百度推廣后臺(tái)
  • 家裝業(yè)務(wù)員怎么做網(wǎng)站營銷網(wǎng)絡(luò)廣告有哪些形式
  • 嘉興營銷型網(wǎng)站上海網(wǎng)絡(luò)推廣優(yōu)化公司
  • 高端網(wǎng)站開發(fā)建設(shè)網(wǎng)站媒體推廣
  • 做數(shù)據(jù)網(wǎng)站手機(jī)百度如何發(fā)布作品
  • 怎么用自己電腦做網(wǎng)站服務(wù)器嗎企業(yè)網(wǎng)站設(shè)計(jì)與實(shí)現(xiàn)論文
  • avada做網(wǎng)站seo公司北京
  • 做啤酒行業(yè)的網(wǎng)站公司網(wǎng)站建設(shè)流程
  • 網(wǎng)站開發(fā)需求描述seo站
  • 怎么做網(wǎng)站在里面填字qq群推廣網(wǎng)站免費(fèi)
  • 怎樣做1個(gè)網(wǎng)站搜索引擎搜索器
  • 站長工具推薦代寫軟文
  • 做設(shè)計(jì)靈感的網(wǎng)站seo團(tuán)隊(duì)
  • 鄭州網(wǎng)站建設(shè)程序網(wǎng)站頁面禁止訪問
  • 公司的企業(yè)文化怎么寫微信搜一搜seo
  • 做的好的微信商城網(wǎng)站什么是seo推廣
  • 網(wǎng)站的后臺(tái)是開發(fā)做的八零云自助建站免費(fèi)建站平臺(tái)
  • 做網(wǎng)站python和php哪個(gè)好學(xué)百度推廣怎么弄
  • 深圳 汽車網(wǎng)站建設(shè)百度網(wǎng)站首頁提交入口
  • seo診斷服務(wù)優(yōu)化什么
  • 中國哪些網(wǎng)站做軟裝seo廠商
  • 四川疫情最新消息今天優(yōu)化服務(wù)
  • 網(wǎng)站設(shè)計(jì)建設(shè)定制中國搜索引擎市場(chǎng)份額
  • 網(wǎng)站建設(shè)策劃方案如何寫愛站網(wǎng)關(guān)鍵詞查詢網(wǎng)站的工具
  • 新媒體營銷策略有哪些百度推廣優(yōu)化中心
  • 備案通過后 添加網(wǎng)站谷歌瀏覽器下載手機(jī)版安卓