二、 轻松使用@Reusable组件复用装饰器 原创

是汉堡黄
发布于 2025-11-2 22:40
浏览
0收藏

🎯 二、 轻松使用@Reusable组件复用装饰器

⭐⭐⭐⭐

🔁 往期

基础单组件显示隐藏使用:🔗 一、 轻松使用@Reusable组件复用装饰器

📌 见解

1️⃣ (List,WaterFlow,Grid)与懒加载搭配使用组件在不可见区域实现回收/复用

2️⃣ 官方已经给出长列表以及多种组件组合类型的复用方式 🔗@hadss/scroll_components❗❗❗

🧩 拆解

🍖 一、LazyForEach搭配使用(List为例)

class MyDataSource implements IDataSource {
  private dataArray: string[] = []
  private listener: DataChangeListener | undefined

  public totalCount(): number {
    return this.dataArray.length
  }

  public getData(index: number): string {
    return this.dataArray[index]
  }

  public pushData(data: string): void {
    this.dataArray.push(data)
  }

  public reloadListener(): void {
    this.listener?.onDataReloaded()
  }

  public registerDataChangeListener(listener: DataChangeListener): void {
    this.listener = listener
  }

  public unregisterDataChangeListener(listener: DataChangeListener): void {
    this.listener = undefined
  }
}

@Entry
@Component
struct ReusableLazyForEachCase {
  private data: MyDataSource = new MyDataSource()

  aboutToAppear() {
    for (let i = 1; i < 100; i++) {
      this.data.pushData(i + "")
    }
  }

  build() {
    Column() {
      List({ space: 5 }) {
        LazyForEach(this.data, (item: string) => {
          ListItem() {
            ReusableLazyForEachCaseChile({ name: item })
          }
        }, (item: string) => item)
      }
      .alignListItem(ListItemAlign.Center)
    }
    .width('100%')
    .height('100%')
  }
}

@Reusable
@Component
export struct ReusableLazyForEachCaseChile {
  @State name: string = ''

  aboutToReuse(params: Record<string, Object>): void {
    this.name = params.name as string
    console.info(`${this.name}---复用`)
  }

  aboutToRecycle() {
    console.info(`${this.name}---回收`)
  }

  build() {
    Column() {
      Text(this.name)
        .fontSize(30)
    }
    .width('80%')
    .justifyContent(FlexAlign.Center)
    .borderWidth(1)
    .height(100)
  }
}

🥩 一、多组件类型(复杂组合可以将各个必要的小组件拆成对应@Reusable,最后在父组件用@Builder组合成固定的几类)

import util from "@ohos.util"

class MockDataItem {
  texts: string | string[] = ''
  type: number = 0
}

const mockData: MockDataItem[] = [
  { texts: '一个汉堡黄', type: 1 },
  { texts: '一个汉堡黄', type: 1 },
  { texts: ['二个汉堡黄', '二个汉堡黄'], type: 2 },
  { texts: ['二个汉堡黄', '二个汉堡黄'], type: 2 },
  { texts: ['二个汉堡黄', '二个汉堡黄'], type: 3 },
  { texts: ['三个汉堡黄', '三个汉堡黄', '三个汉堡黄'], type: 3 },
  { texts: ['三个汉堡黄', '三个汉堡黄', '三个汉堡黄'], type: 3 },
  { texts: '一个汉堡黄', type: 1 },
  { texts: '一个汉堡黄', type: 1 },
  { texts: ['二个汉堡黄', '二个汉堡黄'], type: 2 },
  { texts: ['二个汉堡黄', '二个汉堡黄'], type: 2 },
  { texts: ['三个汉堡黄', '三个汉堡黄', '三个汉堡黄'], type: 3 },
  { texts: ['三个汉堡黄', '三个汉堡黄', '三个汉堡黄'], type: 3 },
  { texts: '一个汉堡黄', type: 1 },
  { texts: '一个汉堡黄', type: 1 },
  { texts: ['二个汉堡黄', '二个汉堡黄'], type: 2 },
  { texts: ['二个汉堡黄', '二个汉堡黄'], type: 2 },
  { texts: ['二个汉堡黄', '二个汉堡黄'], type: 3 },
  { texts: ['三个汉堡黄', '三个汉堡黄', '三个汉堡黄'], type: 3 },
  { texts: ['三个汉堡黄', '三个汉堡黄', '三个汉堡黄'], type: 3 },
  { texts: '一个汉堡黄', type: 1 },
  { texts: '一个汉堡黄', type: 1 },
  { texts: ['二个汉堡黄', '二个汉堡黄'], type: 2 },
  { texts: ['二个汉堡黄', '二个汉堡黄'], type: 2 },
  { texts: ['三个汉堡黄', '三个汉堡黄', '三个汉堡黄'], type: 3 },
  { texts: ['三个汉堡黄', '三个汉堡黄', '三个汉堡黄'], type: 3 },
]

class MyDataSource implements IDataSource {
  private dataArray: MockDataItem[] = []
  private listener: DataChangeListener | undefined

  public totalCount(): number {
    return this.dataArray.length
  }

  public getData(index: number): MockDataItem {
    return this.dataArray[index]
  }

  public pushData(data: MockDataItem): void {
    this.dataArray.push(data)
  }

  public pushArray(data: MockDataItem[]): void {
    this.dataArray = data
  }

  public reloadListener(): void {
    this.listener?.onDataReloaded()
  }

  public registerDataChangeListener(listener: DataChangeListener): void {
    this.listener = listener
  }

  public unregisterDataChangeListener(listener: DataChangeListener): void {
    this.listener = undefined
  }
}

@Entry
@Component
export struct ReusableLazyForEachCase {
  private dataSource: MyDataSource = new MyDataSource()

  aboutToAppear(): void {
    this.dataSource.pushArray(mockData)
  }

  build() {
    Column() {
      List({ space: 5}) {
        LazyForEach(this.dataSource, (item: MockDataItem, idx: number) => {
          if (item.type === 1) {
            oneTextItemComp({ name: item.texts as string, idx })
              .reuseId('oneTextItemComp')
          } else if (item.type === 2) {
            twoTextItemComp({ names: item.texts as string[], idx })
              .reuseId('twoTextItemComp')
          } else if (item.type === 3) {
            threeTextItemComp({ names: item.texts as string[], idx })
              .reuseId('threeTextItemComp')
          }
        }, (item: MockDataItem) => item.toString() + util.generateRandomUUID())
      }
      .cachedCount(1)
      .alignListItem(ListItemAlign.Center)
    }
    .width('100%')
    .height('100%')

  }
}

@Reusable
@Component
struct oneTextItemComp {
  @State name: string = ''
  @State idx: number = 0

  aboutToReuse(params: Record<string, Object>): void {
    this.idx = params.idx as number
    console.info(`${this.idx}---复用`)
  }

  aboutToRecycle() {
    console.info(`${this.idx}---回收`)
  }

  build() {
    Row() {
      Text(this.name)
        .fontSize(16)
    }
    .width('80%')
    .height(80)
    .borderRadius(12)
    .justifyContent(FlexAlign.Center)
    .borderWidth(2)
    .borderColor(Color.Blue)
  }
}

@Reusable
@Component
struct twoTextItemComp {
  @State names: string[] = []
  @State idx: number = 0

  aboutToReuse(params: Record<string, Object>): void {
    this.idx = params.idx as number
    console.info(`${this.idx}---复用`)
  }

  aboutToRecycle() {
    console.info(`${this.idx}---回收`)
  }

  build() {
    Row() {
      Text(this.names[0])
        .fontSize(16)

      Text(this.names[1])
        .fontSize(16)
    }
    .width('80%')
    .height(80)
    .borderRadius(12)
    .justifyContent(FlexAlign.SpaceAround)
    .borderWidth(2)
    .borderColor(Color.Orange)
  }
}

@Reusable
@Component
struct threeTextItemComp {
  @State names: string[] = []
  @State idx: number = 0

  aboutToReuse(params: Record<string, Object>): void {
    this.idx = params.idx as number
    console.info(`${this.idx}---复用`)
  }

  aboutToRecycle() {
    console.info(`${this.idx}---回收`)
  }

  build() {
    Row() {
      Text(this.names[0])
        .fontSize(16)

      Text(this.names[1])
        .fontSize(16)

      Text(this.names[2])
        .fontSize(16)
    }
    .width('80%')
    .height(80)
    .borderRadius(12)
    .justifyContent(FlexAlign.SpaceAround)
    .borderWidth(2)
    .borderColor(Color.Red)
  }
}

📝 合理使用组件抽象能力会让页面结构更加清晰、好维护、易扩展

🌸🌼🌺

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
已于2025-11-2 22:42:28修改
收藏
回复
举报
回复
    相关推荐