目录

场景一:

基础语法:

语法说明:

注意事项:

场景二:

基础语法1:

语法说明:

基础样例:

基础语法2:

语法说明:

基础样例:

场景三:

基础语法:

语法说明:

注意事项:

基础样例:

总结

场景一:

在鸿蒙开发中,基于数组类型数据来进行循环渲染,需要与容器组件配合使用,比如list容器

基础语法:

ForEach(arr: Array<any>,itemGenerator: (item: any, index: number) => void,keyGenerator?: (item: any, index: number) => string)

语法说明:

参数1:需要循环的数组数据

参数2:箭头函数(参数1:是需要循环的数据的每一项,参数2:是每一项的索引)

参数3:键值生成函数(item: 类型, index: number)=>{return 标识}), 生成的键值直接影响UI更新时的结构复用情况

注意事项:

参数3:理论上 数据如果没有变化 结构也不需要变化 结构应该去复用之前的节省性能

实际上 默认键值 index+'__'+JSON.stringify(item)会出现错位情况。如下图所示:

场景二:

在鸿蒙开发中,for循环的一般是在处理纯粹的少量数据业务逻辑,不和ui组件或页面混合使用。

基础语法1:

for (初始值; 条件; 变化量) { 重复执行的代码}

语法说明:
  • let i:定义循环的初始值
  • i < names.length:循环的终止条件
  • i++:循环的变化量
基础样例:

let names: string[] = ['小红', '小明', '大强']

for(let i = 0; i < names.length; i++) {
  console.log('名字是', names[i])
}

    基础语法2:

    • for (let item of 数组名) {重复执行的代码}
    语法说明:
    • for ... of : 在 ... 之中 进行循环
    • item: 声明的一个变量, 用来在循环的时候接收每一个数组元素
    基础样例:

    let names: string[] = ['小红', '小明', '大强']

    for (const item of names) {
      console.log('for...of...名字是', item)
    }

    场景三:

    在鸿蒙开发中,lazyForeach循环可实现数据的懒加载或动态加载的效果,在滚动容器中使用,会按照可视区来创建组件,划出可视区后会销毁组件,降低内存占用。

    基础语法:

    LazyForEach(dataSource: IDataSource, itemGenerator: (item: any, index: number) => void, keyGenerator?: (item: any, index: number) => string)

    语法说明:

    参数一:是一个是获取数据源接口对象,必须实现此接口IDataSource

    参数二:子组件生成函数,会为每一个循环的数据项生成一个子组件

    参数三:键值生成函数,可省略,默认值:index+'__'+JSON.stringify(item)

    注意事项:

    1:LazyForEach必须在容器组件内使用,仅有ListGridSwiper以及WaterFlow组件支持数据懒加载

    2:可以使用属性cachecount设置在可视区外缓存的组件个数。

    3:每次循环只能创建支持可懒加载组件中的某个子组件中一个,比如list容器组件,只能创建listItem子组件。

    4:为了高性能渲染数据,必须通过DataChangeListener对象的onDataChange()方法来更新ui,并且需要键值生成函数生成为一个键值,方可实现。

    基础样例:
    第一步:自定义实现IdataSource接口的类,用于管理listener的监听和事件通知
    class BasicDataSourceLazyForeach implements IDataSource {
      registerDataChangeListener(listener: DataChangeListener): void {
        throw new Error('Method not implemented.');
      }
    
      unregisterDataChangeListener(listener: DataChangeListener): void {
        throw new Error('Method not implemented.');
      }
      private listeners: DataChangeListener[] = [];
      private originDataArray: string[] = [];
    
      totalCount(): number {
        throw new Error('Method not implemented.');
      }
    
      getData(index: number): string {
        throw new Error('Method not implemented.');
      }
     
      notifyDataAdd(index: number): void {
        this.listeners.forEach(listener => {
          listener.onDataAdd(index);
        });
      }
    }

    第二步:自定义用于lazyforeach加载时所需要的数据源的对象数据 并继承第一步的类。

    class MyDataSourceLazyForeach extends BasicDataSourceLazyForeach {
      private dataList: string[] = [];
    
      //获取数据的总数
      public totalCount(): number {
        return this.dataList.length;
      }
    
      //根据索引获取数据
      public getData(index: number): string {
        return this.dataList[index]
      }
    
      public pushData(data: string) {
        //添加数据
        this.dataList.push(data)
        //lazyForeach添加通知事件
        this.notifyDataAdd(this.dataList.length - 1)
      }
    }

    第三步:使用lazyforach进行组件数据动态渲染

    @Entry
    @Component
    struct LazyForeachDemo {
      private data: MyDataSourceLazyForeach = new MyDataSourceLazyForeach();
    
      aboutToAppear() {
        for (let i = 0; i <= 100; i++) {
          this.data.pushData(`我是第${i}号`);
        }
      }
    
      build() {
        List({ space: 3 }) {
          LazyForEach(this.data, (item: string) => {
            ListItem() {
              Row() {
                Text(item).fontSize(50)
             
              }.margin({ left: 10, right: 10 })
            }
          }, (item: string) => item)
        }.cachedCount(5)
      }
    }

    总结

    本文详细的介绍了鸿蒙os开发中使用到的循环,从最基本的情况做了介绍和实现。希望能帮助开发者在实际项目中更好地应用循环来实现我们的具体业务。

    Logo

    讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

    更多推荐