HarmonyOS 组件复用 @Reusable 装饰器的基本使用

2025-06-23 22:51:49
110次阅读
0个评论

HarmonyOS 组件复用 @Reusable 装饰器的基本使用

作用

@Reusable装饰器标记的自定义组件支持视图节点、组件实例和状态上下文的复用,避免重复创建和销毁,提升性能。

原理

使用@Reusable装饰器时,表示该自定义组件可以复用。与@Component结合使用,标记为@Reusable的自定义组件在从组件树

中移除时,组件及其对应的 JS 对象将被放入复用缓存中。后续创建新自定义组件节点时,将复用缓存中的节点,从而节约组件重新

创建的时间。

image-20250623200408525

  1. 标记了@Reusable的自定义组件listItem列表项,在滑动出屏幕一定范围后,从组件树上被移除,组件的对象实例被放入 CustomNode 虚拟结点(与自定义组件一一对应的自定义结点)。

  2. 在不断滑动过程中,列表的RecycleManager将这些CustomNode虚拟结点回收,根据复用标识reuseId分组,形成CachedRecycleNodes的集合,即视图对象的复用缓存池。

  3. 继续滑动,新的listItem需要在列表上显示时,RecycleManager优先从复用缓存池(CachedRecycleNodes集合)中查找对应reuseId的视图对象,然后将新的数据绑定到该视图,重用该节点并添加到组件树上。

适用场景

常见的组件复用开发场景是长列表滑动:在应用展示大量数据的列表界面中,当用户快速地进行滑动操作,列表项反复创建销毁可能导致卡顿等性能问题。这种情况下,使用组件复用机制可以重用已经创建过的列表项视图,提高滑动的流畅度。

基本使用

对于要复用的组件核心是要使用 @Reusable 装饰器 和 reuseId

  • @Reusable 用来定义可复用的组件

  • reuseId 表示该组件属于哪一类,因为可以可以复用好很多不同的组件

定义要复用的组件 Child


@Component

struct Child {

  @State message: string = 'child';



  build() {

    Column() {

      Text(this.message)

        .fontSize(30)

    }

    .borderWidth(1)

    .height(100)

  }

}

组件添加上复用装饰器 @Reusable


@Reusable

@Component

struct Child {

// ...

}

父组件使用


@Entry

@Component

struct Index {

  build() {

    Column() {

      // 如果只有一个复用的组件,可以不用设置reuseId。

      Child()

        .reuseId('Child')

    }

  }

}

效果

image-20250623204001620

子组件属性更新

很多时候,我们要复用的自己,往往是伴随着属性更新的,比如长列表中的联系人列表,结构可能一样,但是内容是不一样。

要实现复用在组件更新,需要搭配组件的声明周期 aboutToReuse

这里模拟长列表中反复切换显示子组件

当一个可复用的自定义组件从复用缓存中重新加入到节点树时,触发 aboutToReuse 生命周期回调,并将组件的构造参数传递

给 aboutToReuse。

父组件控制子组件的显示和属性变更


@Entry

@Component

struct Index {

  @State

  num: number = 1

  @State

  isShow: boolean = false



  build() {

    Column() {

      Button("+")

        .onClick(() => {

          this.isShow = !this.isShow

        })

      if (this.isShow) {

        // 如果只有一个复用的组件,可以不用设置reuseId。

        Child({ message: 'child' + ++this.num })

          .reuseId('Child')

      }

    }

  }

}

子组件使用 aboutToReuse 生命周期 更新属性

params 表示接收父组件传递的属性,对应父组件传递给子组件的 { message: 'child' + ++this.num }


  aboutToReuse(params: Record<string, string>) {

    this.message = params.message

  }

效果

PixPin_2025-06-23_21-08-37

限制条件

  1. @Reusable 装饰器仅用于自定义组件。

  2. ComponentContent 不支持传入@Reusable 装饰器装饰的自定义组件。

  3. @Reusable 装饰器不建议嵌套使用,会增加内存,降低复用效率,加大维护难度。

  4. 避免对@Link/@ObjectLink/@Prop 等自动更新的状态变量,在 aboutToReuse 中重复更新。最佳实践请参考组件复用最佳实践-优化状态管理,精准控制组件刷新范围使用

  5. 在滑动场景中,使用组件复用通常需要用该回调函数去更新组件的状态变量,因此在该回调函数中应避免耗时操作,否则会导致丢帧卡顿。最佳实践请参考主线程耗时操作优化指导-组件复用回调

其他搭配场景

链接

image-20250623211938406

关于我们

关于青蓝逐码组织

如果你兴趣想要了解更多的鸿蒙应用开发细节和最新资讯甚至你想要做出一款属于自己的应用!欢迎在评论区留言或者私信或者看我个人信息,可以加入技术交流群。

image-20250622200325374

收藏00

登录 后评论。没有帐号? 注册 一个。