动态

详情 返回 返回

鴻蒙應用開發——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都渲染出來,耗費時間和內存。

日誌輸入結果:

// 父組件使用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個。

日誌輸出結果:

// 父組件使用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設置不同的顯示模板。

// 父組件使用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) //緩存兩個節點
  }
}
user avatar zourongle 头像 u_9449786 头像 josie_68d213f999ae8 头像 aixiaodekaomianbao_ddkwvd 头像 wsy996 头像
点赞 5 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.