HarmonyOS开发实战:全局自定义组件复用实现规范

简介

默认的组件复用行为,是将子组件放在父组件的缓存池里,受到这个限制,不同父组件中的相同子组件无法复用,推荐的解决方案是将父组件改为builder函数,让子组件共享组件复用池,但是由于在一些应用场景下,父组件承载了复杂的带状态的业务逻辑,而builder是无状态的,修改会导致难以维护,因此开发者可以使用BuilderNode自行管理组件复用池。

实现思路

  1. 将要生成自定义组件地方用NodeContainer占位,将NodeContainer内部的NodeController按照组件类型分别存储在NodePool中。
  2. 每次需要创建子组件时,优先从NodePool中取出一个组件,如果NodePool中没有可复用的组件则重新创建一个,否则就更新一下数据。当NodeController销毁时,回收到NodePool中,供下次使用。

数据结构

image-20240531161153519

创建和销毁过程中复用池的流程

image-20240531164427730

应用场景

在应用开发中,会遇到需要页面切换的场景,比如某些视频APP的首页,就是一个List(标题)+Swiper(列表页面)实现的Tabs切换场景(如图1所示)。Swiper中每个页面都使用瀑布流加载视频列表,各个瀑布流中的子组件有可能是相同的布局,为了提升应用性能,就会有跨页面复用子组件的需求。但是在ArkUI提供的常规复用中,复用池是放在父组件中的,这就导致跨页面时无法复用上一个页面瀑布流中的子组件。此时就可以使用BuilderNode自定义一个全局的组件复用池,根据页面状态创建、回收、复用子组件,实现组件的跨页面复用。

图1 应用场景示意图

custom_reusable_pool

示例代码

下面通过常规复用和自定义组件复用池两种方式,对比组件复用的性能。

常规复用

  1. 使用List+Swiper实现Tabs页面切换。

    // ...
    List() {
      ForEach(this.arrayTitle, (title: Title, index: number) => {
        ListItem() {
          TitleView({
            title: title, clickListener: () => {
              if (title.isSelected) {
                return;
              }
              this.swiperController.changeIndex(index, true);
              this.arrayTitle[index].isSelected = true;
              this.arrayTitle[this.selectIndex].isSelected = false;
              this.selectIndex = index;
            }
          })
          // ...
        }
      })
    }
    .height(30)
    .listDirection(Axis.Horizontal)
    
    Swiper(this.swiperController) {
      // 使用LazyForEach,使Swiper页面按需加载,而不是一次全部创建
      LazyForEach(this.array, () => {
        TabComp()
      }, (title: string) => title)
    }
    .loop(false)
    .onChange((index: number) => { 
      if (this.selectIndex !== index) {
        this.arrayTitle[index].isSelected = true;
        this.arrayTitle[this.selectIndex].isSelected = false;
        this.selectIndex = index;
      }
    })
    .cachedCount(0) // 此处设置cachedCount为0,便于性能对比,实际开发中可按需设置
    // ...
  2. 使用Swiper组件实现轮播图,使用WaterFlow组件实现瀑布流加载数据,并给自定义组件设置reuseId,用于组件复用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值