本文转载自《#2023盲盒+码# OpenHarmony组件复用示例》,作者zhushangyuan_

● 摘要:在开发应用时,有些场景下的自定义组件具有相同的组件布局结构,仅有状态变量等承载数据的差异。这样的组件缓存起来,需要使用到该组件时直接复用,

● 减少了创建和渲染的时间,可以提高帧率和用户性能体验。本文会介绍开发OpenHarmony应用时如何使用组件复用能力。关键字:OpenHarmony HarmonyOS 鸿蒙 ForEach LazyForEach 循环渲染

概述

在开发应用时,有些场景下的自定义组件具有相同的组件布局结构,仅有状态变量等承载数据的差异。这样的组件缓存起来,需要使用到该组件时直接复用,

减少重复创建和渲染的时间,从而提高应用页面的加载速度和响应速度。在OpenHarmony应用开发时,自定义组件被@Reusable装饰器修饰时表示该自定义组件可以复用。在父自定义组件下创建的可复用组件从组件树上移除后,会被加入父自定义组件的可复用节点缓存里。

在父自定义组件再次创建可复用组件时,会通过更新可复用组件的方式,从缓存快速创建可复用组件。这就是OpenHarmony的组件复用机制。本文会介绍开发OpenHarmony应用时如何使用组件复用能力。

环境准备

准备一个DevEco Studio,使用真机或者Simulator模拟器来验证。更多关于DevEco Studio的信息,请访问:https://developer.harmonyos.com/cn/develop/deveco-studio/

组件复用接口

OpenHarmony SDK文件ets\component\common.d.ts的自定义组件的生命周期里定义了aboutToReuse方法,如下:

自定义组件的生命周期回调函数用于通知用户该自定义组件的生命周期,这些回调函数是私有的,在运行时由开发框架在特定的时间进行调用,不能从应用程序中手动调用这些回调函数。

当一个可复用的自定义组件从复用缓存中重新加入到节点树时,触发aboutToReuse生命周期回调,并将组件的构造参数传递给aboutToReuse。aboutToReuse函数的参数是字典类型的,键为组件的构造参数变量名称,值为组件的构造参数实际取值。

该声明周期函数从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;
......
}

  

开发实践

我们看下组件复用的实际使用案例。示例中,会创建一个图片列表页面,使用懒加载LazyForEach,以及组件复用能力。

创建数据源

首先,创建了一个业务对象类MyImage,包含一个image_id图片编号和image_path图片路径。根据实际业务的不同,会有差异,此例仅用于演示。

然后,创建一个数据源类ImageListDataSource,并构造一个列表对象imageList。

可以看到,构造了10000条记录。 在工程的/resources/images文件夹下有50张图片。

每条记录中,包含一个编号,从0到9999。

记录中,还一个一个图片路径,不同的记录,编号不会重复,图片路径可能重复。

至此,数据源类创建完毕。

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]
}
......
}

  

创建复用组件

创建好数据源类后,我们再看下可复用组件的代码。

使用装饰器@Reusable来标记一个组件是否属于可复用组件。

我们创建的可复用组件有一个状态变量@State item,构造该自定义组件时,父组件会给子母件传递构造数据。

还需要实现组件复用声明周期回调函数aboutToReuse,在这个函数里,通过params把构造数据传递给可复用组件。

我们在函数aboutToReus里,再单独加个一个打印函数,用于在组件复用时,输出一条日志记录。

需要注意的是,正常情况下,aboutToReuse函数里除了构造参数传值,不要做任何耗时操作。

在可复用组件的build()方法里,为每条记录渲染一行,包含图片、图片编号和图片路径。

图片编号可以识别渲染的是哪一条数据,用于验证组件复用了正确的组件。

@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父组件里,可以调用可复用组件MyListItem。通过{ item: item }完成父子组件参数传递。

reuseId参数是可选的,用于标记可复用组件的复用类型。属性参数的注释如下:

  /**
* 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)
}
}
}

  

注意事项

可以访问站点https://gitee.com/openharmony/developtools_ace_ets2bundle/tree/master/compiler/test/utForPartialUpdate/render_decorator/@recycle查看组件复用的一些示例,这些是用于测试的例子。

@Reusable之前的装饰器的名称为@Recycle,旧名称不使用了。ForEach渲染控制具有全展开的特性,不能触发组件复用。

总结

本文介绍了开发OpenHarmony应用时如何使用组件复用能力,提供代码示例,期望帮助关注组件复用的开发者朋友们。

如有任何问题,欢迎交流讨论。

参考资料

[1] Sample聊天实例应用

[2] 自定义组件的生命周期

[3] 组件复用场景

[4] 组件复用一些示例

OpenHarmony组件复用示例的更多相关文章

  1. 10.Web组件复用

    1.静态包含(一个指令) 在软件工程中构建可复用组件可极大的提高软件生产效率.增强系统的可维护性HTML标记对于一个web应用系统中的页面都是通用的,比如公司标志.版权声明.导航菜单JSP中引用的we ...

  2. React组件复用的方式

    React组件复用的方式 现前端的工程化越发重要,虽然使用Ctrl+C与Ctrl+V同样能够完成需求,但是一旦面临修改那就是一项庞大的任务,于是减少代码的拷贝,增加封装复用能力,实现可维护.可复用的代 ...

  3. Yii Framework 开发教程Zii组件-Tabs示例

    有关Yii Tab类: http://www.yiichina.com/api/CTabView http://www.yiichina.com/api/CJuiTabs http://blog.cs ...

  4. 前端UI组件复用工具

    "懒"是第一生产力. 代码复用总是程序员喜闻乐见的,前端组件化的最终目的就是复用,今天我们就将深入探讨如何实现UI组件的复用. 通常我们所说的组件往往是包含业务逻辑的前端组件,而这 ...

  5. vue-router 组件复用问题

    组件系统是Vue的一个重要组成部分,它可以将一个复杂的页面抽象分解成许多小型.独立.可复用的组件,通过组合组件来组成应用程序,结合vue-router的路由功能将各个组件映射到相应的路由上,通过路由的 ...

  6. 基于CMS的组件复用实践

    目前前端项目大多基于Vue.React.Angular等框架来实现,这一类框架都有一个明显的特点:基于模块化以及组件化思维.所以,开发者在使用上述框架时,实际上是在写一个一个的组件,并且组件与组件之间 ...

  7. QML从文件加载组件简单示例

    QML从文件加载组件简单示例 文件目录列表: Project1.pro QT += quick CONFIG += c++ CONFIG += declarative_debug CONFIG += ...

  8. 【React -- 5/100】 组件复用

    组件复用 React组件复用概述 思考:如果两个组件中的部分功能相似或相同,该如何处理? 处理方式:复用相似的功能 复用什么? state 操作state的方法 两种方式: render props模 ...

  9. Vue.js 组件复用和扩展之道

    软件编程有一个重要的原则是 D.R.Y(Don't Repeat Yourself),讲的是尽量复用代码和逻辑,减少重复.组件扩展可以避免重复代码,更易于快速开发和维护.那么,扩展 Vue 组件的最佳 ...

  10. Svelte入门——Web Components实现跨框架组件复用

    Svelte 是构建 Web 应用程序的一种新方法,推出后一直不温不火,没有继Angular.React和VUE成为第四大框架,但也没有失去热度,无人问津.造成这种情况很重要的一个原因是,Svelte ...

随机推荐

  1. python各版本新特性

    # py3.7 https://docs.python.org/zh-cn/3/whatsnew/3.7.html # py3.8 https://docs.python.org/zh-cn/3/wh ...

  2. CXP2.0的相机是否可以使用CXP1.1的Grabber

    可以 答案是肯定的. 目前CXP共有2个发布版本: 2011年发布CXP1.1 2021年发布CXP2.1,向后兼容,新标准增加了同步功能.数据率放大了一倍. 只要是符合CXP标准.接插件匹配,那么C ...

  3. 【Azure 应用服务】如何从App Service for Linux 的环境中下载Container中非Home目录下的文件呢?

    问题描述 在App Service for Linux的环境中,我们能通过SSH进入到Container的环境中,并且可以通过在kudu站点的URL后面添加 /newui 打开一个适用于Linux环境 ...

  4. 今天接到一个根据excel来更新数据库的需求,用php写个小脚本

    需求大概内容是,excel中有些条目需要删除.有些需要新增,就需要基于这份excel生成删.增的SQL. 要求是这样的:蓝色要删除的,黄色是要新增的,白色和灰色的不用管. 我第一时间就在想:还得识别单 ...

  5. win上vscode出现undefined reference to `__imp_WSACleanup'

    示例代码 #include <iostream> // 推荐加上宏定义 #define WIN32_LEAN_AND_MEAN #include <winsock2.h> #i ...

  6. 使用内网nginx代理rancher

    需求: rancher 部署在 192.168.188.167服务器上 控制台访问地址 https://192.168.188.167:8443 在本地只有192.168.80.111有权限访问, 需 ...

  7. Vue实现图片瀑布流

    在线演示地址:点击前往 一,创建一个Waterfall组件 代码如下: <template> <div class="waterfall"> <!-- ...

  8. 2FA双因素认证 - 原理和应用

    主页 个人微信公众号:密码应用技术实战 个人博客园首页:https://www.cnblogs.com/informatics/ 引言 我们在登陆网站.或者通过VPN访问公司内网时,除了输入用户口令外 ...

  9. axios post xml data方法

    axios#request(config) axios#get(url[,config]) axios#delete(url[,config]) axios#head(url[,config]) ax ...

  10. Docker 安装成功(win10家庭版)

    https://desktop.docker.com/win/stable/Docker Desktop Installer.exe 安装遇到了 然后 更新 这个 https://wslstorest ...