HarmonyOS鸿蒙Next中懒加载插入数据

HarmonyOS鸿蒙Next中懒加载插入数据 arkTs中,如果使用懒加载我如何批量插入数据,然后不造成全量刷新呢?

5 回复

开发者您好,

关于您提到的“懒加载”,是否指的是 lazyForEach 的使用?另外,针对批量插入场景,是否可以参考以下本地测试的实现方式?

若遇到长列表数据刷新时出现闪烁问题,建议参考:长列表数据刷新闪烁-行业常见问题-综合办公类行业实践-场景化知识 - 华为HarmonyOS开发者

测试代码:

// BasicDataSource实现了IDataSource接口,用于管理listener监听,以及通知LazyForEach数据更新
export class BasicDataSource implements IDataSource {
  private listeners: DataChangeListener[] = [];
  private originDataArray: StringData[] = [];

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

  public getData(index: number): StringData {
    return this.originDataArray[index];
  }

  // 该方法为框架侧调用,为LazyForEach组件向其数据源处添加listener监听
  registerDataChangeListener(listener: DataChangeListener): void {
    if (this.listeners.indexOf(listener) < 0) {
      this.listeners.push(listener);
    }
  }

  // 该方法为框架侧调用,为对应的LazyForEach组件在数据源处去除listener监听
  unregisterDataChangeListener(listener: DataChangeListener): void {
    const pos = this.listeners.indexOf(listener);
    if (pos >= 0) {
      this.listeners.splice(pos, 1);
    }
  }

  // 通知LazyForEach组件需要重载所有子组件
  notifyDataReload(): void {
    this.listeners.forEach(listener => {
      listener.onDataReloaded();
    });
  }

  // 通知LazyForEach组件需要在index对应索引处添加子组件
  notifyDataAdd(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataAdd(index);
      // 写法2:listener.onDatasetChange([{type: DataOperationType.ADD, index: index}]);
    });
  }

  // 通知LazyForEach组件在index对应索引处数据有变化,需要重建该子组件
  notifyDataChange(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataChange(index);
      // 写法2:listener.onDatasetChange([{type: DataOperationType.CHANGE, index: index}]);
    });
  }

  // 通知LazyForEach组件需要在index对应索引处删除该子组件
  notifyDataDelete(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataDelete(index);
      // 写法2:listener.onDatasetChange([{type: DataOperationType.DELETE, index: index}]);
    });
  }

  // 通知LazyForEach组件将from索引和to索引处的子组件进行交换
  notifyDataMove(from: number, to: number): void {
    this.listeners.forEach(listener => {
      listener.onDataMove(from, to);
      // 写法2:listener.onDatasetChange(
      //         [{type: DataOperationType.EXCHANGE, index: {start: from, end: to}}]);
    });
  }

  notifyDatasetChange(operations: DataOperation[]): void {
    this.listeners.forEach(listener => {
      listener.onDatasetChange(operations);
    });
  }
}

class StringData {
  message: string;
  imgSrc: Resource;

  constructor(message: string, imgSrc: Resource) {
    this.message = message;
    this.imgSrc = imgSrc;
  }
}

class InitialDataSource extends BasicDataSource {
  private dataArray: StringData[] = [];

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

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

  public pushData(data: StringData): void {
    this.dataArray.push(data);
    this.notifyDataAdd(this.dataArray.length - 1);
  }
}

@Entry
@Component
struct InitialRendering {
  private data: InitialDataSource = new InitialDataSource();

  aboutToAppear() {
    for (let i = 0; i <= 5; i++) {
      this.data.pushData(new StringData(`Click to add ${i}`, $r('app.media.xxx')));
    }
  }

  build() {
    Column() {
      Button('pushDataBatch').onClick((event: ClickEvent) => {
        for (let i = 0; i <= 1; i++) {
          this.data.pushData(new StringData(`pushDataBatch ${i}`, $r('app.media.xxx')));
        }
      });
      List({ space: 3 }) {
        LazyForEach(this.data, (item: StringData) => {
          ListItem() {
            Row() {
              Text(item.message).fontSize(20)
                .onAppear(() => {
                  console.info('text appear:' + item.message);
                });
              Image(item.imgSrc)
                .width(100)
                .height(100);
            }.margin({ left: 10, right: 10 });
          }
        })
      };
    };
  }
}

更多关于HarmonyOS鸿蒙Next中懒加载插入数据的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


@Component
struct StockBondLinkage {
  @State currentIndex: number = 0
  private listScroller: Scroller = new Scroller()
  private bondChartSettings: RenderingContextSettings = new RenderingContextSettings(true)
  private bondChartContext: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.bondChartSettings)
  private stockChartSettings: RenderingContextSettings = new RenderingContextSettings(true)
  private stockChartContext: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.stockChartSettings)
  // 模拟数据
  @State stockBondList: StockBondItem[] = []

  aboutToAppear(): void {
    this.stockBondList = stockBondList
  }

  build() {
    Column() {
      // 顶部导航栏
      this.NavigationBar()

      // 今日涨幅TOP标签栏
      this.TopFilterBar()

      // 主要展示卡片(股债对比)
      this.MainCompareCard()

      // 列表表头
      this.ListHeader()

      // 股债联动列表
      this.BondList()
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#1A1A1A')
  }

  // 顶部导航栏
  @Builder
  NavigationBar() {
    Row() {
      Text('<')
        .fontSize(22)
        .fontColor('#FFFFFF')
        .width(40)

      Text('股债联动')
        .fontSize(18)
        .fontColor('#FFFFFF')
        .fontWeight(FontWeight.Medium)
        .layoutWeight(1)
        .textAlign(TextAlign.Center)

      Row() {
        Text('↻')
          .fontSize(20)
          .fontColor('#FFFFFF')
          .margin({ right: 20 })

        Text('🔍')
          .fontSize(18)
          .fontColor('#FFFFFF')
      }
      .width(60)
      .justifyContent(FlexAlign.End)
    }
    .width('100%')
    .height(44)
    .padding({ left: 12, right: 12 })
    .backgroundColor('#0D0D0D')
  }

  // 今日涨幅TOP标签栏
  @Builder
  TopFilterBar() {
    Row() {
      Text('今日涨幅 TOP')
        .fontSize(13)
        .fontColor('#888888')

      Text('0.11%')
        .fontSize(13)
        .fontColor('#00AA00')
        .margin({ left: 8 })

      Text('专用设备')
        .fontSize(11)
        .fontColor('#FF4444')
        .border({ width: 1, color: '#FF4444', radius: 2 })
        .padding({
          left: 6,
          right: 6,
          top: 2,
          bottom: 2
        })
        .margin({ left: 10 })

      Blank()

      Text('最相关')
        .fontSize(13)
        .fontColor('#FFFFFF')
    }
    .width('100%')
    .padding({
      left: 12,
      right: 12,
      top: 10,
      bottom: 10
    })
    .backgroundColor('#1A1A1A')
  }

  // 主要展示卡片
  @Builder
  MainCompareCard() {
    Row() {
      // 左侧转债信息
      Column() {
        // 标题行:名称和价格
        Row() {
          Text('耐普转02')
            .fontSize(14)
            .fontColor('#FF4444')
          Text('157.300')
            .fontSize(15)
            .fontColor('#FF4444')
            .fontWeight(FontWeight.Bold)
            .margin({ left: 6 })
        }
        .width('100%')
        .justifyContent(FlexAlign.Start)

        // 代码和涨幅
        Row() {
          Text('123265')
            .fontSize(11)
            .fontColor('#666666')
          Text('+57.30%')
            .fontSize(11)
            .fontColor('#FF4444')
            .margin({ left: 6 })
        }
        .width('100%')
        .margin({ top: 2 })

        // 走势图区域(带Y轴标签)
        Row() {
          // 左侧Y轴
          Column() {
            Text('157.300')
              .fontSize(9)
              .fontColor('#FF4444')
            Blank()
            Text('100.000')
              .fontSize(9)
              .fontColor('#666666')
            Blank()
            Text('42.700')
              .fontSize(9)
              .fontColor('#00AA00')
          }
          .height(75)
          .width(45)
          .justifyContent(FlexAlign.SpaceBetween)
          .alignItems(HorizontalAlign.Start)

          // 走势图
          Canvas(this.bondChartContext)
            .width(80)
            .height(75)
            .backgroundColor('#1A1A1A')
            .onReady(() => {
              this.drawBondChart()
            })

          // 右侧Y轴
          Column() {
            Text('57.3%')
              .fontSize(9)
              .fontColor('#FF4444')
            Blank()
            Text('-57.3%')
              .fontSize(9)
              .fontColor('#00AA00')
          }
          .height(75)
          .width(35)
          .justifyContent(FlexAlign.SpaceBetween)
          .alignItems(HorizontalAlign.End)
        }
        .width('100%')
        .margin({ top: 6 })
      }
      .layoutWeight(1)
      .padding({
        left: 8,
        right: 4,
        top: 8,
        bottom: 8
      })

      // 分隔线
      Divider()
        .vertical(true)
        .height('80%')
        .color('#333333')
        .strokeWidth(0.5)

      // 右侧正股信息
      Column() {
        // 标题行:名称和价格
        Row() {
          Text('耐普矿机')
            .fontSize(14)
            .fontColor('#FFFFFF')
          Text('49.58')
            .fontSize(15)
            .fontColor('#00AA00')
            .fontWeight(FontWeight.Bold)
            .margin({ left: 6 })
        }
        .width('100%')
        .justifyContent(FlexAlign.Start)

        // 代码和跌幅
        Row() {
          Text('300818')
            .fontSize(11)
            .fontColor('#666666')
          Text('-9.11%')
            .fontSize(11)
            .fontColor('#00AA00')
            .margin({ left: 6 })
        }
        .width('100%')
        .margin({ top: 2 })

        // 走势图区域(带Y轴标签)
        Row() {
          // 左侧Y轴
          Column() {
            Text('62.29')
              .fontSize(9)
              .fontColor('#FF4444')
            Blank()
            Text('54.55')
              .fontSize(9)
              .fontColor('#666666')
            Blank()
            Text('46.81')
              .fontSize(9)
              .fontColor('#00AA00')
          }
          .height(75)
          .width(35)
          .justifyContent(FlexAlign.SpaceBetween)
          .alignItems(HorizontalAlign.Start)

          // 走势图
          Canvas(this.stockChartContext)
            .width(90)
            .height(75)
            .backgroundColor('#1A1A1A')
            .onReady(() => {
              this.drawStockChart()
            })

          // 右侧Y轴
          Column() {
            Text('14.2%')
              .fontSize(9)
              .fontColor('#FF4444')
            Blank()
            Text('-14.2%')
              .fontSize(9)
              .fontColor('#00AA00')
          }
          .height(75)
          .width(32)
          .justifyContent(FlexAlign.SpaceBetween)
          .alignItems(HorizontalAlign.End)
        }
        .width('100%')
        .margin({ top: 6 })
      }
      .layoutWeight(1)
      .padding({
        left: 4,
        right: 8,
        top: 8,
        bottom: 8
      })
    }
    .width('100%')
    .height(200)
    .backgroundColor('#1A1A1A')
    .margin({ top: 1 })
  }

  // 绘制转债走势图(红色填充上涨)
  drawBondChart() {
    let ctx = this.bondChartContext
    let w = 80
    let h = 75

    ctx.clearRect(0, 0, w, h)

    ctx.beginPath()
    ctx.moveTo(0, h)
    ctx.lineTo(0, h * 0.9)
    ctx.lineTo(w * 0.3, h * 0.85)
    ctx.lineTo(w * 0.5, h * 0.8)
    ctx.lineTo(w * 0.7, h * 0.3)
    ctx.lineTo(w * 0.85, h * 0.1)
    ctx.lineTo(w, h * 0.05)
    ctx.lineTo(w, h)
    ctx.closePath()

    ctx.fillStyle = '#FF4444'
    ctx.globalAlpha = 0.6
    ctx.fill()
    ctx.globalAlpha = 1.0
  }

  // 绘制正股走势图(白色线+黄色均线)
  drawStockChart() {
    let ctx = this.stockChartContext
    let w = 90
    let h = 75
    let midY = h * 0.5

    ctx.clearRect(0, 0, w, h)

    ctx.beginPath()
    ctx.moveTo(0, midY - 5)
    ctx.lineTo(w * 0.1, midY - 8)
    ctx.lineTo(w * 0.2, midY - 3)
    ctx.lineTo(w * 0.3, midY + 2)
    ctx.lineTo(w * 0.4, midY - 5)
    ctx.lineTo(w * 0.5, midY + 8)
    ctx.lineTo(w * 0.6, midY + 5)
    ctx.lineTo(w * 0.7, midY + 12)
    ctx.lineTo(w * 0.8, midY + 8)
    ctx.lineTo(w * 0.9, midY + 15)
    ctx.lineTo(w, midY + 18)
    ctx.strokeStyle = '#FFFFFF'
    ctx.lineWidth = 1
    ctx.stroke()

    ctx.beginPath()
    ctx.moveTo(0, midY)
    ctx.lineTo(w * 0.2, midY + 2)
    ctx.lineTo(w * 0.4, midY + 5)
    ctx.lineTo(w * 0.6, midY + 8)
    ctx.lineTo(w * 0.8, midY + 12)
    ctx.lineTo(w, midY + 15)
    ctx.strokeStyle = '#FFAA00'
    ctx.lineWidth = 1
    ctx.stroke()
  }

  // 列表表头
  @Builder
  ListHeader() {
    Row() {
      Text('股债联动')
        .fontSize(12)
        .fontColor('#666666')
        .layoutWeight(1)

      Text('转债报价▼')
        .fontSize(12)
        .fontColor('#666666')
        .layoutWeight(1)
        .textAlign(TextAlign.End)

      Text('正股报价▼')
        .fontSize(12)
        .fontColor('#666666')
        .layoutWeight(1)
        .textAlign(TextAlign.End)

      Text('溢价率▼')
        .fontSize(12)
        .fontColor('#666666')
        .layoutWeight(1)
        .textAlign(TextAlign.End)

      Row() {
        Text('量比')
          .fontSize(12)
          .fontColor('#666666')
        Text('▶')
          .fontSize(10)
          .fontColor('#666666')
          .margin({ left: 4 })
      }
      .layoutWeight(1)
      .justifyContent(FlexAlign.End)
    }
    .width('100%')
    .padding({
      left: 12,
      right: 12,
      top: 10,
      bottom: 8
    })
    .backgroundColor('#1A1A1A')
  }

  // 股债联动列表
  @Builder
  BondList() {
    List({ scroller: this.listScroller }) {
      ForEach(this.stockBondList, (item: StockBondItem) => {
        ListItem() {
          this.BondListItem(item)
        }
      }, (item: StockBondItem) => item.bondCode)
    }
    .width('100%')
    .layoutWeight(1)
    .backgroundColor('#1A1A1A')
    .scrollBar(BarState.Off)
  }

  // 列表项
  @Builder
  BondListItem(item: StockBondItem) {
    Row() {
      // 股债名称
      Column() {
        Text(item.bondName)
          .fontSize(14)
          .fontColor('#FFFFFF')
        Text(item.bondCode)
          .fontSize(10)
          .fontColor('#666666')
          .margin({ top: 2 })
      }
      .layoutWeight(1)
      .alignItems(HorizontalAlign.Start)

      // 转债报价
      Column() {
        Text(item.bondPrice.toFixed(3))
          .fontSize(13)
          .fontColor('#FF4444')
        Text((item.bondChange >= 0 ? '+' : '') + item.bondChange.toFixed(2) + '%')
          .fontSize(10)
          .fontColor('#FF4444')
          .margin({ top: 2 })
      }
      .layoutWeight(1)
      .alignItems(HorizontalAlign.End)

      // 正股报价
      Column() {
        Text(item.stockPrice > 0 ? item.stockPrice.toFixed(2) : '--')
          .fontSize(13)
          .fontColor(item.stockChange >= 0 ? '#FF4444' : '#00AA00')
        Text(item.stockChange !== 0 ? ((item.stockChange >= 0 ? '+' : '') + item.stockChange.toFixed(2) + '%') : '--')
          .fontSize(10)
          .fontColor(item.stockChange >= 0 ? '#FF4444' : '#00AA00')
          .margin({ top: 2 })
      }
      .layoutWeight(1)
      .alignItems(HorizontalAlign.End)

      // 溢价率
      Text(item.premiumRate.toFixed(2) + '%')
        .fontSize(13)
        .fontColor(item.premiumRate >= 0 ? '#FF4444' : '#00AA00')
        .layoutWeight(1)
        .textAlign(TextAlign.End)

      // 量比
      Text(item.volumeRatio > 0 ? item.volumeRatio.toFixed(2) : '--')
        .fontSize(13)
        .fontColor('#FFFFFF')
        .layoutWeight(1)
        .textAlign(TextAlign.End)
    }
    .width('100%')
    .padding({
      left: 12,
      right: 12,
      top: 10,
      bottom: 10
    })
    .backgroundColor('#1A1A1A')
  }
}
// 股债联动数据模型
interface StockBondItem {
  bondName: string
  bondCode: string
  bondPrice: number
  bondChange: number
  stockPrice: number
  stockChange: number
  premiumRate: number
  volumeRatio: number
}

const stockBondList: StockBondItem[] = [
  {
    bondName: '耐普转02',
    bondCode: '123265',
    bondPrice: 157.300,
    bondChange: 57.30,
    stockPrice: 49.58,
    stockChange: -9.11,
    premiumRate: 21.96,
    volumeRatio: 0
  },
  {
    bondName: '汇车退债',
    bondCode: '404004',
    bondPrice: 57.780,
    bondChange: 43.85,
    stockPrice: 0.07,
    stockChange: 0,
    premiumRate: -42.22,
    volumeRatio: 0.61
  },
  {
    bondName: '联瑞转债',
    bondCode: '118064',
    bondPrice: 226.512,
    bondChange: 20.00,
    stockPrice: 66.79,
    stockChange: 2.60,
    premiumRate: 115.53,
    volumeRatio: 60.16
  },
  {
    bondName: '富淼转债',
    bondCode: '118029',
    bondPrice: 142.608,
    bondChange: 11.03,
    stockPrice: 27.42,
    stockChange: 14.11,
    premiumRate: -3.26,
    volumeRatio: 11.63
  },
  {
    bondName: '百川转2',
    bondCode: '127075',
    bondPrice: 149.000,
    bondChange: 7.58,
    stockPrice: 9.59,
    stockChange: 9.98,
    premiumRate: 16.99,
    volumeRatio: 5.71
  },
  {
    bondName: '广联转债',
    bondCode: '123182',
    bondPrice: 166.900,
    bondChange: 4.81,
    stockPrice: 38.41,
    stockChange: 4.09,
    premiumRate: -0.75,
    volumeRatio: 1.88
  },
  {
    bondName: '亿田转债',
    bondCode: '123235',
    bondPrice: 183.300,
    bondChange: 3.65,
    stockPrice: 33.76,
    stockChange: 3.24,
    premiumRate: 15.70,
    volumeRatio: 1.86
  },
  {
    bondName: '宇邦转债',
    bondCode: '123224',
    bondPrice:
/**
 * 构建数据框(显示当前选中位置的数据)
 * 数据框会跟随位置线移动
 * 注意:@Builder中不能写逻辑代码,所有计算都在updateDataBoxInfo中完成
 */
@Builder
buildDataBox() {
  // 数据框UI构建(只使用状态变量,不进行计算)
  Column() {
    // 时间标题
    Text(this.dataBoxTimeLabel)
      .fontSize(14)
      .fontColor('#FFFFFF')
      .fontWeight(FontWeight.Bold)
      .margin({ bottom: 8 })

    // ========== 上证指数部分 ==========
    Row() {
      // 蓝色虚线图标
      this.buildDashedLine(this.shanghaiColor, 16)
      Text('上证指数')
        .fontSize(12)
        .fontColor(this.shanghaiColor)
        .fontWeight(FontWeight.Bold)
        .margin({ left: 4 })
    }
    .width('100%')
    .margin({ bottom: 4 })

    // 上证风向得分
    Row() {
      Text('风向得分:')
        .fontSize(11)
        .fontColor('#CCCCCC')
      Text(this.shanghaiPredictScores[0].toFixed(2) + '分')
        .fontSize(11)
        .fontColor('#FFFFFF')
      Text('  ' + this.dataBoxShanghaiRating)
        .fontSize(11)
        .fontColor('#AAAAAA')
    }
    .width('100%')

    // 上证实际涨幅
    Row() {
      Text('实际涨幅:')
        .fontSize(11)
        .fontColor('#CCCCCC')
      Text(this.dataBoxShanghaiChange)
        .fontSize(11)
        .fontColor(this.dataBoxShanghaiChange.startsWith('+') ? '#F56C6C' : '#4CAF50')
    }
    .width('100%')
    .margin({ bottom: 8 })

    // ========== 全A市场部分 ==========
    Row() {
      // 橙色虚线图标
      this.buildDashedLine(this.allASharesColor, 16)
      Text('全A市场')
        .fontSize(12)
        .fontColor(this.allASharesColor)
        .fontWeight(FontWeight.Bold)
        .margin({ left: 4 })
    }
    .width('100%')
    .margin({ bottom: 4 })

    // 全A风向得分
    Row() {
      Text('风向得分:')
        .fontSize(11)
        .fontColor('#CCCCCC')
      Text(this.allAPredictScores[0].toFixed(2) + '分')
        .fontSize(11)
        .fontColor('#FFFFFF')
      Text('  ' + this.dataBoxAllARating)
        .fontSize(11)
        .fontColor('#AAAAAA')
    }
    .width('100%')

    // 全A实际涨幅
    Row() {
      Text('实际涨幅:')
        .fontSize(11)
        .fontColor('#CCCCCC')
      Text(this.dataBoxAllAChange)
        .fontSize(11)
        .fontColor(this.dataBoxAllAChange.startsWith('+') ? '#F56C6C' : '#4CAF50')
    }
    .width('100%')
  }
  .width(150) // 数据框宽度
  .backgroundColor('rgba(0, 0, 0, 0.5)')
  .borderRadius(8)
  .padding({
    left: 12,
    right: 12,
    top: 10,
    bottom: 10
  })
  .margin({
    left: this.dataBoxAlign === Alignment.TopStart ? this.dataBoxX : 0,
    right: this.dataBoxAlign === Alignment.TopEnd ? this.dataBoxX : 0,
    // top: this.dataBoxY
  })
  .shadow({
    radius: 4,
    color: 'rgba(0, 0, 0, 0.15)',
    offsetX: 0,
    offsetY: 2
  })

  // .align(this.dataBoxAlign)
}

在HarmonyOS Next中,懒加载插入数据通常指使用LazyForEach组件配合数据源管理。数据源需继承BaseLazyDataSource并实现onDataReloaded、totalCount、getData方法。当列表项即将进入可视区域时,LazyForEach会调用getData加载数据。插入新数据时,需在数据源中更新数据集合,并调用notifyDataReloaded或notifyDataAdd方法触发UI刷新。整个过程由ArkUI框架管理按需加载,避免一次性渲染大量数据。

在HarmonyOS Next的ArkTS中,使用懒加载(例如通过LazyForEach)进行批量数据插入且避免全量刷新,核心在于只更新数据源(@State/@Link修饰的数组),并利用LazyForEach的组件复用机制。以下是具体方法:

关键步骤

  1. 数据源管理:使用[@State](/user/State)[@Link](/user/Link)修饰的数组(如Array<YourDataType>)作为LazyForEach的数据源。
  2. 批量插入数据:直接对数据源数组进行批量操作(例如pushsplice或解构赋值),ArkUI框架会自动触发差异更新。
  3. 避免全量刷新LazyForEach会根据数据源的变化,仅创建、复用或移除对应的子组件,不会重新渲染整个列表。

代码示例

// 1. 定义数据源
[@State](/user/State) dataArray: Array<YourDataType> = []; // 初始数据

// 2. 批量插入数据(例如追加新数据)
private insertBatchData(newData: Array<YourDataType>) {
  // 使用数组解构或concat生成新数组,触发状态更新
  this.dataArray = this.dataArray.concat(newData); // 或 [...this.dataArray, ...newData]
}

// 3. 在UI中使用LazyForEach
LazyForEach(
  this.dataArray, // 数据源
  (item: YourDataType) => item.id, // 键值生成器
  (item: YourDataType) => {
    // 子组件构建函数
    YourListItemComponent({ item: item })
  }
)

注意事项

  • 数据标识:确保每个数据项有唯一键值(如id),以便LazyForEach正确复用组件。
  • 不可变数据:更新数据源时需生成新数组(如用concat或解构),直接修改原数组(如this.dataArray.push(...))可能不会触发UI更新。
  • 性能优化:对于超大数据集,建议分页加载,避免一次性插入过多数据导致内存压力。

通过以上方式,批量插入数据时只有新增项对应的组件会被渲染,现有组件不会刷新,从而实现高效更新。

回到顶部