本文转载自《#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. SpringBoot面试题的零碎整理

    面试题1:简述一下Springboot相对SSM做了哪些提升? 首先,SpringBoot是采用"约定大于配置"(Convention over Configuration)的理念 ...

  2. vscode 点击 import 的对象 from 带有 @ 不能自动跳转 - 要配置 jsconfig.json

    问题 vscode 点击 import 的对象 from 带有 @ 不能自动跳转 - 要配置 jsconfig.json 答案 根目录 创建 jsconfig.json 20220808 更新 inc ...

  3. ADS1299开发调试总结之寄存器使用说明简析

    一 前记 在生物生理信号测量领域,ads12xx系列是一个无法绕过去的存在.笔者最近几个项目围绕着动物生理信号测量来做.所以用ads12xx比较多一些. 中间遇到了一些问题,这里做一个总结吧. 二 寄 ...

  4. Hamming(汉明)窗的原理介绍及实例解析

    概念   在数字信号处理过程中,每次FFT变换只能对有限长度的时域数据进行变换,因此,需要对时域信号进行信号截断.即使是周期信号,如果截断的时间长度不是周期的整数倍(周期截断),那么,截取后的信号将会 ...

  5. 投屏项目中Sink端CPU占用过高问题

    一.背景 今天来总结一下,自己在项目中遇到的一个CPU占用过高的问题,详细的结束从发现到定位在到解决问题的过程. 原因是性能测试那边提出了一个bug,就是在投屏过程中,平板端也就是Sink端功耗非常高 ...

  6. 使用docker-compose管理freeswitch容器

    概述 之前的文章我们介绍过如何将freeswitch做成docker镜像,也使用命令行模式正常启动了fs的docker容器. 但是当我们需要同时管理多个docker容器的时候,还是使用docker-c ...

  7. d3d12龙书阅读----d3d渲染流水线

    d3d12龙书阅读----d3d渲染流水线 输入装配器阶段 在输入装配器阶段,会从显存中读取顶点与索引这种几何数据,然后根据图形基元的类型,根据索引将顶点组装起来. d3d中的图形基元 我们来看看几种 ...

  8. 【2311. 小于等于 K 的最长二进制子序列】贪心

    class Solution { public static void main(String[] args) { Solution solution = new Solution(); System ...

  9. CYQ.Data 操作 Json 性能测试:对比 Newtonsoft.Json

    前言: 在 CYQ.Data 版本更新的这么多年,中间过程的版本都在完善各种功能. 基于需要支持或兼容的代码越多,很多时候,常规思维,都把相关功能完成,就结束了. 实现过程中,无法避免的会用到大量的反 ...

  10. .Net依赖注入神器Scrutor(上)

    前言 从.Net Core 开始,.Net 平台内置了一个轻量,易用的 IOC 的框架,供我们在应用程序中使用,社区内还有很多强大的第三方的依赖注入框架如: Autofac DryIOC Grace ...