鸿蒙应用开发——Repeat组件的使用

【高心星出品】

Repeat组件的使用

概念

Repeat基于数组类型数据来进行循环渲染,一般与容器组件配合使用。

Repeat根据容器组件的有效加载范围(屏幕可视区域+预加载区域)加载子组件。当容器滑动/数组改变时,Repeat会根据父容器组件的布局过程重新计算有效加载范围,并管理列表子组件节点的创建与销毁。

  • Repeat必须在滚动类容器组件内使用,仅有List、ListItemGroup、Grid、Swiper以及WaterFlow组件支持Repeat懒加载场景。

    循环渲染只允许创建一个子组件,子组件应当是允许包含在容器组件中的子组件。例如:Repeat与List组件配合使用时,子组件必须为ListItem组件。

  • Repeat不支持V1装饰器,混用V1装饰器会导致渲染异常。

  • Repeat当前不支持动画效果。

  • 滚动容器组件内只能包含一个Repeat。以List为例,不建议同时包含ListItem、ForEach、LazyForEach,不建议同时包含多个Repeat。

  • 当Repeat与自定义组件或@Builder函数混用时,必须将RepeatItem类型整体进行传参,组件才能监听到数据变化。详见Repeat与@Builder混用。

Repeat子组件由.each()和.template()属性定义,只允许包含一个子组件。当页面首次渲染时,Repeat根据当前的有效加载范围(屏幕可视区域+预加载区域)按需创建子组件。如下图所示:

repeat默认会分配1个预加载节点,通过cachecount可以认为调整预加载节点个数。

案例

repeat全量加载数组案例:

下面案例使用list加载全量数组元素,第一运行的时候就会把100个listitem都渲染出来,耗费时间和内存。

日志输入结果:

scss 复制代码
// 父组件使用Repeat渲染列表
@Entry
@Component
struct repeatpage {
  @State items: string[] = [];
  aboutToAppear() {
    // 初始化数据
    for (let i = 0; i < 100; i++) {
      this.items.push(`列表项 ${i}`);
    }
  }
​
  build() {
    List() {
      Repeat(this.items)
        // 遍历每个数组元素
        .each((item: RepeatItem<string>) => {
          ListItem() {
           Text(item.item)
             .fontSize(20)
             .width('100%')
             .textAlign(TextAlign.Center)
          }.onAppear(()=>{
            // 当listitem渲染的时候调用
            console.log('gxxt ',item.item+' 出现了')
          })
        })
    }
    .width('100%')
  }
}
repeat开启懒加载和设置预加载数量

下面案例开启了virtualScroll懒加载和cachedCount预加载数量,可以看到第一次只渲染了可见区域的listitem,随着滑动重用预加载的节点。第一次渲染了30的listem,缓存了两个节点,所以加载的数据为32个。

日志输出结果:

scss 复制代码
// 父组件使用Repeat渲染列表
@Entry
@Component
struct repeatpage {
  @State items: string[] = [];
  aboutToAppear() {
    // 初始化数据
    for (let i = 0; i < 100; i++) {
      this.items.push(`列表项 ${i}`);
    }
  }
​
  build() {
    List() {
      Repeat(this.items)
        // 遍历每个数组元素
        .each((item: RepeatItem<string>) => {
          ListItem() {
           Text(item.item)
             .fontSize(20)
             .width('100%')
             .textAlign(TextAlign.Center)
          }.onAppear(()=>{
            // 当listitem渲染的时候调用
            console.log('gxxt ',item.item+' 出现了')
          })
        })// 开启懒加载
        .virtualScroll()
    }
    .width('100%')
    .cachedCount(2) //缓存两个节点
  }
}
repeat设置加载模板

下面案例中给repeat设置通用模板和huang模板和hong模板,根据index设置不同的显示模板。

scss 复制代码
// 父组件使用Repeat渲染列表
@Entry
@Component
struct repeatpage {
  @State items: string[] = [];
​
  aboutToAppear() {
    // 初始化数据
    for (let i = 0; i < 100; i++) {
      this.items.push(`列表项 ${i}`);
    }
  }
​
  build() {
    List() {
      Repeat(this.items)// 遍历每个数组元素
        .each((item: RepeatItem<string>) => {
          ListItem() {
            Text(item.item)
              .fontSize(20)
              .width('100%')
              .textAlign(TextAlign.Center)
          }.onAppear(() => {
            // 当listitem渲染的时候调用
            console.log('gxxt ', item.item + ' 出现了')
          })
        })
        .template('huang', (item: RepeatItem<string>) => {
          ListItem() {
            Text(item.item)
              .fontSize(20)
              .width('100%')
              .textAlign(TextAlign.Center)
              .backgroundColor(Color.Yellow)
          }.onAppear(() => {
            // 当listitem渲染的时候调用
            console.log('gxxt ', item.item + ' 出现了')
          })
        })
        .template('hong', (item: RepeatItem<string>) => {
          ListItem() {
            Text(item.item)
              .fontSize(20)
              .width('100%')
              .textAlign(TextAlign.Center)
              .backgroundColor(Color.Red)
          }.onAppear(() => {
            // 当listitem渲染的时候调用
            console.log('gxxt ', item.item + ' 出现了')
          })
        })
        .templateId((item: string, index: number) => {
          // 下标被3除余1 加载huang模板  被3除余2 加载hong模板 其他的加载each的通用模板
          if (index % 3 == 1) {
            return 'huang'
          } else if (index % 3 == 2) {
            return 'hong'
          } else {
            return ''
          }
        })// 开启懒加载
        .virtualScroll()
    }
    .width('100%')
    .cachedCount(2) //缓存两个节点
  }
}
相关推荐
遇到困难睡大觉哈哈5 小时前
HarmonyOS —— Remote Communication Kit 拦截器(Interceptor)高阶定制能力笔记
笔记·华为·harmonyos
遇到困难睡大觉哈哈6 小时前
HarmonyOS —— Remote Communication Kit 定制处理行为(ProcessingConfiguration)速记笔记
笔记·华为·harmonyos
氤氲息7 小时前
鸿蒙 ArkTs 的WebView如何与JS交互
javascript·交互·harmonyos
遇到困难睡大觉哈哈7 小时前
HarmonyOS支付接入证书准备与生成指南
华为·harmonyos
赵浩生7 小时前
鸿蒙技术干货10:鸿蒙图形渲染基础,Canvas绘图与自定义组件实战
harmonyos
赵浩生7 小时前
鸿蒙技术干货9:deviceInfo 设备信息获取与位置提醒 APP 整合
harmonyos
BlackWolfSky7 小时前
鸿蒙暂未归类知识记录
华为·harmonyos
L、2189 小时前
Flutter 与开源鸿蒙(OpenHarmony):跨平台开发的新未来
flutter·华为·开源·harmonyos
L、21810 小时前
Flutter 与 OpenHarmony 深度融合实践:打造跨生态高性能应用(进阶篇)
javascript·flutter·华为·智能手机·harmonyos