HarmonyOS ArkTS 组件复用详解:理解 @Reusable 装饰器

HarmonyOS ArkTS 组件复用详解:理解 @Reusable 装饰器

一起来构建生态吧~

在 HarmonyOS ArkUI 的开发中,我们常常会封装自定义组件,以便在多个地方重复使用。 但当一个页面中重复创建、销毁大量组件时,例如在动态列表里滑动大量列表项,这会造成性能开销明显增大。这个问题在复杂界面或低端设备上尤其明显。

为了解决这个问题,HarmonyOS 提供了一个非常实用的装饰器: @Reusable 装饰器 ------ 它能让自定义组件具备复用能力 ,最大限度减少组件重复创建和销毁的成本,从而提升渲染性能。华为开发者官网


一、为什么需要组件复用?

在声明式 UI 框架中,每次渲染组件树时:

  1. 假如组件被移除(例如滚动出屏幕外),默认会销毁实例
  2. 当它再次显示时又要重新创建,构建新的对象
  3. 这就造成了大量的 对象创建、布局计算、渲染开销

尤其在以下场景下会出现性能瓶颈:

  • 滚动大量列表项(如消息列表、商品列表)
  • 动态条件渲染大量结构相同的子组件
  • 频繁切换视图导致大量组件反复创建/销毁

这时如果我们能 复用旧的组件实例(并更新其参数),就能省掉这笔开销。

@Reusable 正是为此设计的,它让你标记的自定义组件具备"复用池"能力,从而减少重复创建,提高性能。华为开发者官网


二、@Reusable 到底做了什么?

当你给一个自定义组件加上 @Reusable 装饰器以后:

这个组件从组件树移除时,并不是立即销毁 系统会把它和对应的 JSView 对象缓存到复用池 下一次需要创建同类型组件时 → 会优先从复用池取出旧实例而不是新建 然后把新数据赋值进去重新渲染

这样做的好处:

  • 减少重复的 对象创建/销毁
  • 降低 内存分配和 GC 频率
  • 渲染速度更快、滚动更流畅
  • 在复杂界面和高频场景下提升整体性能华为开发者官网

三、使用条件与限制

在实际使用中,有几个关键点你一定要注意:

1. 只能用于自定义组件

@Reusable 不能用于内置组件(如 Text、Button、Image 等),也不能用于简化的 Builder 函数。

要搭配 @Component 一起使用。华为开发者官网

2. 不支持和 @Builder 混用

如果同时用在 Builder 上,会报错;这种组合不被支持。CSDN

3. ComponentContent 不支持

某些用于对话框/弹窗内容的组件结构(ComponentContent)不允许使用 @ReusableCSDN

4. 复用池和父组件作用域

组件复用通常是"在同一父组件作用域下"发生的。 不同父组件可能维护不同的复用缓存池。bbs.itying.com


四、基本使用示例(真实项目可直接抄)

下面我们做一个 简单的列表项复用示例 :每个列表项本来会频繁创建/销毁,我们用 @Reusable 优化它。


1) 创建可复用组件

typescript 复制代码
 import { Component, Reusable, Prop } from '@ohos.arkui';
 ​
 @Reusable
 @Component
 export struct MyListItem {
   @Prop item: number = 0
 ​
   aboutToAppear(): void {
     console.log("组件首次创建:", this.item)
   }
 ​
   aboutToReuse(): void {
     console.log("组件被复用:", this.item)
   }
 ​
   build() {
     Text(`这是第 ${this.item} 项`)
       .fontSize(20)
       .width("100%")
       .textAlign(TextAlign.Center)
   }
 }

解释:

  • @Reusable 标记这个组件支持复用
  • aboutToAppear() 在组件第一次创建并加入组件树前触发
  • aboutToReuse() 当组件从复用池重新被拿出来时触发(可以用于初始化/重置)CSDN

2) 在父组件中使用它

scss 复制代码
 @Entry
 @Component
 export struct Index {
   @State arrayNum: number[] = []
 ​
   aboutToAppear(): void {
     this.pushArray()
   }
 ​
   pushArray() {
     this.arrayNum = []
     for (let index = 0; index < 10; index++) {
       this.arrayNum.push(index)
     }
   }
 ​
   build() {
     Column() {
 ​
       Row({ space: 20 }) {
         Button("清空列表")
           .onClick(() => {
             this.arrayNum = []
           })
         Button("创建列表")
           .onClick(() => {
             this.pushArray()
           })
       }
 ​
       List() {
         ForEach(this.arrayNum, (item) => {
           ListItem() {
             MyListItem({ item: item })
           }
         })
       }
       .width("100%")
       .height("90%")
     }
   }
 }

效果:

  • 当你清空列表再创建的时候,不会完全销毁旧组件(除非缓存池满了)
  • 控制台会输出 aboutToReuse 日志,说明组件被复用了CSDN

五、常见实战技巧 + 注意事项

1. 配合生命周期方法初始化状态

复用组件时,不会自动清理内部 @State 状态,如果你需要它每次看起来像"新创建",可以在 aboutToReuse() 里重置。华为开发者官网


2. 给不同组件分不同的 reuseId

如果父组件里多种复用组件,给它们不同的 reuseId 可以避免互相干扰。

scss 复制代码
 MyListItem({ item: item }).reuseId('MyListItem')

(部分实现中 reuseId 会影响缓存池分组)华为开发者官网


3. 不要滥用

虽然组件复用能提升性能,但也不是所有组件都需要标记。

  • 少量不会频繁创建/销毁的页面组件无需加复用
  • 纯静态结构组件也没太大意义

六、为什么复用比传统创建/销毁更快?

在声明式框架里,创建组件涉及:

  • 实例化对象
  • 解析 JSX / build() 逻辑
  • 生成虚拟 DOM
  • 计算布局和样式
  • 在底层生成原生 View

每一步都有性能成本。 复用跳过了"重新创建对象+构建树"的过程,它只是:

  1. 从缓存池取实例
  2. 更新属性/状态
  3. 触发局部刷新

这能显著减少重复工作,尤其在长列表滚动时体现更明显。bbs.itying.com


七、总结(整理成可复用的经验)

特性 是否支持
可复用组件 ✔️
序列化缓存 ✔️
状态池隔离 ✔️(需要手动管理)
与 Builder 混用

核心收益:性能优化 > 代码复用逻辑简化 最佳实践:列表项、频繁切换视图的子组件优先标记 @Reusable 华为开发者官网

相关推荐
lili-felicity3 小时前
React Native 鸿蒙跨平台开发:LayoutAnimation 实现鸿蒙端按钮点击的缩放反馈动画
react native·react.js·harmonyos
哈__5 小时前
React Native 鸿蒙跨平台开发:Dimensions 屏幕尺寸获取
react native·华为·harmonyos
奋斗的小青年!!6 小时前
Flutter跨平台开发适配OpenHarmony:手势识别实战应用
flutter·harmonyos·鸿蒙
搬砖的kk6 小时前
Cordova 适配鸿蒙系统(OpenHarmony) 全解析:技术方案、环境搭建与实战开发
华为·开源·harmonyos
不爱吃糖的程序媛6 小时前
OpenHarmony 通用C/C++三方库 标准化鸿蒙化适配
c语言·c++·harmonyos
程序猿追7 小时前
鸿蒙PC应用开发深度实战:一次开发、多端适配的沉浸式音乐播放器迁移实践
华为·harmonyos
行者968 小时前
Flutter跨平台开发:安全检测组件适配OpenHarmony
flutter·harmonyos·鸿蒙
小雨下雨的雨8 小时前
Flutter 框架跨平台鸿蒙开发 —— GridView 控件之多维网格美学
flutter·华为·交互·harmonyos·鸿蒙系统
小雨下雨的雨9 小时前
Flutter跨平台开发实战: 鸿蒙与循环交互艺术:无限循环的 Banner 引擎
flutter·ui·华为·交互·harmonyos·鸿蒙系统
奋斗的小青年!!9 小时前
Flutter与鸿蒙深度融合:打造物理引擎驱动的3D卡片交互体验
flutter·3d·harmonyos·鸿蒙