HarmonyOS5 便捷生活类——TabContent预加载问题

加入下方官方班级,得鸿蒙礼盒

一起拿鸿蒙礼盒,戳我戳我!!

本期活动时间:2025年8月1日-12月31日


问题现象

在aboutToAppear回调中使用preloadItems方法来实现TabContent组件的预加载,结果未生效,为什么?如何解决?

背景知识

  • aboutToAppear函数在创建自定义组件的新实例后,在执行其build()函数之前执行,早于Tabs组件的渲染。preloadItems方法能够控制Tabs预加载指定子节点。调用该接口后会一次性加载所有指定的子节点,预加载到不存在的索引时就会报错。
  • TabContent仅在Tabs中使用,对应一个切换页签的内容视图。而其onWillShow逻辑回调,在TabContent将要显示的时候触发。场景包括TabContent首次显示,TabContent切换,页面切换,窗口前后台切换。
  • Router路由与导航Navigation各自的生命周期不同。

问题定位

在Tabs组件中,将预加载方法preloadItems在aboutToAppear方法中直接调用,由于aboutToAppear会在Tabs组件完成渲染前就被调用,Tabs组件的索引也就获取不到,因此导致preloadItems方法预加载了不存在的索引,从而预加载失败并且产生报错。

分析结论

预加载方法preloadItems在aboutToAppear回调中被直接调用,导致预加载了不存在的索引,从而致使预加载失败。

修改建议

aboutToAppear被调用的时候Tabs组件尚未完成渲染,导致Tabs的预加载方法加载不存在的索引,从而预加载失败,使用执行时间相对靠后的生命周期执行预加载方法即可预防问题,方案如下:

方案一:使用导航路由页面生命周期。

  • 场景一:使用Router页面生命周期

    在Router页面生命周期中,onPageShow回调在页面每次显示时都会触发一次,可以在该生命周期中调用预加载方法preloadItems,通过打印日志的方法来判断TabContent预加载是否成功。

    调用onPageShow。
     

    运行日志参考如下:

  • onPageShow(): void {
    this.tabsController.preloadItems([0, 1, 2, 3])
    .then(() => {
    console.info('onPageShow preloadItems success.')
    })
    .catch((error: BusinessError) => {
    console.error(`Failed to publish notification, error:${error}`);
    })
    }

  • 场景二:使用Navigation页面生命周期

    在Navigation页面生命周期中,onAppear回调组件挂载显示后触发,可以在该生命周期中调用预加载方法preloadItems,通过打印日志的方法来判断TabContent预加载是否成功。

    调用onAppear。

     

    运行日志参考如下:

  • .onAppear(() => {
    this.tabsController.preloadItems([0, 1, 2, 3])
    .then(() => {
    console.info('onAppear preloadItems success.')
    })
    .catch((error: BusinessError) => {
    console.error(`Failed to publish notification, error:${error}`);
    })
    })

方案二:使用TabContent生命周期。

  • TabContent支持onWillShow逻辑回调,该回调会在TabContent将要显示的时候触发,也可以在该生命周期中调用预加载方法preloadItems,并且onWillShow回调是TabContent支持的回调函数,Tabs每次切换时都会触发该回调,因此每个TabContent都要设置,数据量较大时需要做节流处理。调用onWillShow。
     

    运行日志参考如下:

  • TabContent() {
    MyComponent({ color: '#E67C92' })
    }
    .tabBar(SubTabBarStyle.of('pink'))
    .onWillShow(() => {
    this.tabsController.preloadItems([0, 2, 3])
    .then(() => {
    console.info('onWillShow preloadItems success.')
    })
    .catch((error: BusinessError) => {
    console.error(`Failed to publish notification, error:${error}`);
    })
    })

常见FAQ

Q:Tabs组件预加载生效之后会调用aboutToAppear方法吗?

A:被预加载的TabContent中的对应控件的aboutToAppear方法会被调用,可以添加日志来验证。

Q:有没有办法能够在aboutToAppear回调里进行预加载?

A:确认TabContent创建完成后再进行Tabs组件的预加载,可以通过同步获取数据再进行预加载。

总结

由于aboutToAppear回调会在执行其build()函数之前执行,因此会导致preloadItems方法去预加载还未完成渲染的TabContent组件,需要使用执行时间相对靠后的生命周期,本文主要提供了两种方案,onPageShow回调和onAppear回调都能够在TabContent渲染完成之后调用,而onWillShow回调只有在滑动到相应TabContent子页面才会被调用,并且在数据量较多时需要注意节流问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值