加入下方官方班级,得鸿蒙礼盒
本期活动时间: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子页面才会被调用,并且在数据量较多时需要注意节流问题。

被折叠的 条评论
为什么被折叠?



