概述
在開發(fā)應(yīng)用時(shí),有些場(chǎng)景下的自定義組件具有相同的組件布局結(jié)構(gòu),僅有狀態(tài)變量等承載數(shù)據(jù)的差異。這樣的組件緩存起來(lái),需要使用到該組件時(shí)直接復(fù)用, 減少重復(fù)創(chuàng)建和渲染的時(shí)間,從而提高應(yīng)用頁(yè)面的加載速度和響應(yīng)速度。
在OpenHarmony應(yīng)用開發(fā)時(shí),自定義組件被@Reusable裝飾器修飾時(shí)表示該自定義組件可以復(fù)用。在父自定義組件下創(chuàng)建的可復(fù)用組件從組件樹上移除后,會(huì)被加入父自定義組件的可復(fù)用節(jié)點(diǎn)緩存里。 在父自定義組件再次創(chuàng)建可復(fù)用組件時(shí),會(huì)通過(guò)更新可復(fù)用組件的方式,從緩存快速創(chuàng)建可復(fù)用組件。這就是OpenHarmony的組件復(fù)用機(jī)制。
本文會(huì)介紹開發(fā)OpenHarmony應(yīng)用時(shí)如何使用組件復(fù)用能力。
環(huán)境準(zhǔn)備
準(zhǔn)備一個(gè)DevEco Studio,使用真機(jī)或者Simulator模擬器來(lái)驗(yàn)證。
組件復(fù)用接口
OpenHarmony SDK文件ets\component\common.d.ts的自定義組件的生命周期里定義了aboutToReuse方法,如下:
自定義組件的生命周期回調(diào)函數(shù)用于通知用戶該自定義組件的生命周期,這些回調(diào)函數(shù)是私有的,在運(yùn)行時(shí)由開發(fā)框架在特定的時(shí)間進(jìn)行調(diào)用,不能從應(yīng)用程序中手動(dòng)調(diào)用這些回調(diào)函數(shù)。
當(dāng)一個(gè)可復(fù)用的自定義組件從復(fù)用緩存中重新加入到節(jié)點(diǎn)樹時(shí),觸發(fā)aboutToReuse生命周期回調(diào),并將組件的構(gòu)造參數(shù)傳遞給aboutToReuse。aboutToReuse函數(shù)的參數(shù)是字典類型的,鍵為組件的構(gòu)造參數(shù)變量名稱,值為組件的構(gòu)造參數(shù)實(shí)際取值。
該聲明周期函數(shù)從API version 10開始,該接口支持在ArkTS卡片中使用。
declare class CustomComponent extends CommonAttribute {
......
/**
* aboutToReuse Method
*
* @param { { [key: string]: unknown } } params - Custom component init params.
* @syscap SystemCapability.ArkUI.ArkUI.Full
* @crossplatform
* @since 10
*/
aboutToReuse?(params: { [key: string]: unknown }): void;
......
}
開發(fā)實(shí)踐
我們看下組件復(fù)用的實(shí)際使用案例。示例中,會(huì)創(chuàng)建一個(gè)圖片列表頁(yè)面,使用懶加載LazyForEach,以及組件復(fù)用能力。
創(chuàng)建數(shù)據(jù)源
首先,創(chuàng)建了一個(gè)業(yè)務(wù)對(duì)象類MyImage,包含一個(gè)image_id圖片編號(hào)和image_path圖片路徑。根據(jù)實(shí)際業(yè)務(wù)的不同,會(huì)有差異,此例僅用于演示。
然后,創(chuàng)建一個(gè)數(shù)據(jù)源類ImageListDataSource,并構(gòu)造一個(gè)列表對(duì)象imageList。
可以看到,構(gòu)造了10000條記錄。 在工程的/resources/images文件夾下有50張圖片。
每條記錄中,包含一個(gè)編號(hào),從0到9999。
記錄中,還一個(gè)一個(gè)圖片路徑,不同的記錄,編號(hào)不會(huì)重復(fù),圖片路徑可能重復(fù)。
至此,數(shù)據(jù)源類創(chuàng)建完畢。
export class MyImage {
image_id: string
image_path: string
constructor(image_id: string, image_path: string) {
this.image_id = image_id
this.image_path = image_path
}
}
export class ImageListDataSource extends BasicDataSource {
private imageList: MyImage[] = []
public constructor() {
super()
for (let i = 0;i < 10000; i++) {
let imageStr = `/resources/images/photo${(i % 50).toString()}.jpg`
this.imageList.push(new MyImage(i.toString(), imageStr))
}
}
public totalCount(): number {
return this.imageList.length
}
public getData(index: number): MyImage {
return this.imageList[index]
}
......
}
創(chuàng)建復(fù)用組件
創(chuàng)建好數(shù)據(jù)源類后,我們?cè)倏聪驴蓮?fù)用組件的代碼。
使用裝飾器@Reusable來(lái)標(biāo)記一個(gè)組件是否屬于可復(fù)用組件。
我們創(chuàng)建的可復(fù)用組件有一個(gè)狀態(tài)變量@State item,構(gòu)造該自定義組件時(shí),父組件會(huì)給子母件傳遞構(gòu)造數(shù)據(jù)。
還需要實(shí)現(xiàn)組件復(fù)用聲明周期回調(diào)函數(shù)aboutToReuse,在這個(gè)函數(shù)里,通過(guò)params把構(gòu)造數(shù)據(jù)傳遞給可復(fù)用組件。
我們?cè)诤瘮?shù)aboutToReus里,再單獨(dú)加個(gè)一個(gè)打印函數(shù),用于在組件復(fù)用時(shí),輸出一條日志記錄。
需要注意的是,正常情況下,aboutToReuse函數(shù)里除了構(gòu)造參數(shù)傳值,不要做任何耗時(shí)操作。
在可復(fù)用組件的build()方法里,為每條記錄渲染一行,包含圖片、圖片編號(hào)和圖片路徑。
圖片編號(hào)可以識(shí)別渲染的是哪一條數(shù)據(jù),用于驗(yàn)證組件復(fù)用了正確的組件。
@Reusable
@Component
struct MyListItem {
@State item: MyImage = new MyImage('', '')
aboutToReuse(params) {
this.item = params.item
Logger.info(TAG, 'aboutToReuse-,item=' + this.item.toString())
}
build() {
Row({ space: 10 }) {
Image(this.item.image_path)
.width(50)
.height(50)
.borderRadius(5)
.autoResize(false)
.syncLoad(true)
Blank()
Text(this.item.image_id)
.fontColor(Color.Black)
.fontSize(15)
Blank()
Text(this.item.image_path)
.fontColor(Color.Black)
.fontSize(15)
}
}
}
入口組件
在我們的@Ent */-·- 件里,在List父組件里,可以調(diào)用可復(fù)用組件MyListItem。
通過(guò){ item: item }完成父子組件參數(shù)傳遞。
reuseId參數(shù)是可選的,用于標(biāo)記可復(fù)用組件的復(fù)用類型。屬性參數(shù)的注釋如下:
/**
* Reuse id is used for identify the reuse type for each custom node.
*
* @param { string } id - The id for reusable custom node.
* @syscap SystemCapability.ArkUI.ArkUI.Full
* @crossplatform
* @since 10
*/
reuseId(id: string)
入口組件的示例代碼如下:
@Entry
@Component
struct Index {
private data: ImageListDataSource = new ImageListDataSource()
build() {
List({ space: 3 }) {
LazyForEach(this.data, (item: MyImage) => {
ListItem() {
MyListItem({ item: item })
// .reuseId(item.image_id)
}
}, item => item)
}
}
}
本文主要是對(duì)鴻蒙開發(fā)基礎(chǔ)當(dāng)中的OpenHarmony技術(shù)組件復(fù)用示例,更多鴻蒙開發(fā)OpenHarmony技術(shù)可以在主頁(yè)閱讀更多,下面分享一張鴻蒙4.0的學(xué)習(xí)路線圖:(略縮版)
高清完整版可以在主頁(yè)保存↓↓↓(附文檔鴻蒙4.0)
注意事項(xiàng)
@Reusable之前的裝飾器的名稱為@Recycle,舊名稱不使用了。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-803727.html
ForEach渲染控制具有全展開的特性,不能觸發(fā)組件復(fù)用。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-803727.html
到了這里,關(guān)于鴻蒙開發(fā)OpenHarmony組件復(fù)用案例的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!