
回复
@Reusable
装饰器标记的自定义组件支持视图节点、组件实例和状态上下文的复用,避免重复创建和销毁,提升性能。
使用@Reusable
装饰器时,表示该自定义组件可以复用。与@Component
结合使用,标记为@Reusable
的自定义组件在从组件树
中移除时,组件及其对应的 JS 对象将被放入复用缓存中。后续创建新自定义组件节点时,将复用缓存中的节点,从而节约组件重新
创建的时间。
@Reusable
的自定义组件listItem
列表项,在滑动出屏幕一定范围后,从组件树上被移除,组件的对象实例被放入 CustomNode 虚拟结点(与自定义组件一一对应的自定义结点)。RecycleManager
将这些CustomNode
虚拟结点回收,根据复用标识reuseId分组,形成CachedRecycleNodes
的集合,即视图对象的复用缓存池。listItem
需要在列表上显示时,RecycleManager
优先从复用缓存池(CachedRecycleNodes
集合)中查找对应reuseId
的视图对象,然后将新的数据绑定到该视图,重用该节点并添加到组件树上。常见的组件复用开发场景是长列表滑动:在应用展示大量数据的列表界面中,当用户快速地进行滑动操作,列表项反复创建销毁可能导致卡顿等性能问题。这种情况下,使用组件复用机制可以重用已经创建过的列表项视图,提高滑动的流畅度。
对于要复用的组件核心是要使用 @Reusable
装饰器 和 reuseId
@Reusable
用来定义可复用的组件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')
}
}
}
很多时候,我们要复用的自己,往往是伴随着属性更新的,比如长列表中的联系人列表,结构可能一样,但是内容是不一样。
要实现复用在组件更新,需要搭配组件的声明周期 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')
}
}
}
}
params 表示接收父组件传递的属性,对应父组件传递给子组件的
{ message: 'child' + ++this.num }
aboutToReuse(params: Record<string, string>) {
this.message = params.message
}
如果你兴趣想要了解更多的鸿蒙应用开发细节和最新资讯,甚至你想要做出一款属于自己的应用!欢迎在评论区留言或者私信或者看我个人信息,可以加入技术交流群。