ArkTs中使用ForEach循环渲染

文章概叙

本文主要使用一个简单的例子介绍一下ArkTs中是如何进行循环渲染的。以及对ForEach接口的用法做出介绍

列表循环

无论是在哪一端进行开发,循环渲染永远是一个避不开的话题。尤其是在现在的主流框架中,基本都存在if判断是否显示,for循环渲染的接口,在ArkTs中自然也存在,ArkTS是使用ForEach接口循环渲染的。

ForEach接口基于数组类型数据来进行循环渲染,需要与容器组件配合使用,且接口返回的组件应当是允许包含在ForEach父容器组件中的子组件。例如,ListItem组件要求ForEach的父容器组件必须为List组件。

介绍起来有点麻烦,正好结合在我们的tab中,将其整合起来,介绍下如何使用forEach来循环渲染。

介绍情况

之前的例子中,我们是分两次来实现TabContent的,代码如下

  TabContent() {
    Text(`这个是${this.tabList[0].name}`)
  }
  .tabBar(this.TabBuilder(
    this.tabList[0].name,
    0,
    this.tabList[0].selected_icon,
    this.tabList[0].unselected_icon)
  )
  .backgroundColor("#ccc")

自然可以发现两次代码的重复率很高,唯一的区别就是下标、文字、icon的区别。

且两组数据都是从同一个tabList的数组中拿出来的,所以这儿的情况就很适合使用forEach接口了。

开始代码

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

以上是官网中对forEach接口的参数示例,其中

  • arr

数据源,为Array类型的数组。为必需参数

  • itemGenerator

组件生成函数。为必需参数,也就是我们生成页面的地方

  • keyGenerator

键值生成函数,非必须,也就是我们的唯一标识。

在ForEach循环渲染过程中,系统会为每个数组元素生成一个唯一且持久的键值,用于标识对应的组件。当这个键值变化时,ArkUI框架将视为该数组元素已被替换或修改,并会基于新的键值创建一个新的组件。

键值的重要性在于,当我们的列表数据更新,我们要重新做一次循环渲染的时候,如果键值没有发生变化,则ArkUI不会对其进行更新.

结合到我们的项目中,既我们要对tabContent进行forEach循环渲染,所以我们的代码需要这么改动

Tabs({ barPosition: BarPosition.End }) {
  ForEach(this.tabList, (item: any, index: number) => {
    TabContent() {
      Text(`这个是${item.name}`)
    }
    .tabBar(
      this.TabBuilder(
        item.name,
        index,
        item.selected_icon,
        item.unselected_icon)
    )
    .backgroundColor("#ccc")
  })
}

在第三行中,我们抛出来的组件是TabContent,这是因为我们的Tabs中需要使用到TabContent组件,所以就解释了刚刚后半句的

需要与容器组件配合使用,且接口返回的组件应当是允许包含在ForEach父容器组件中的子组件
ok,更新后的整个代码如下

@Entry
@Component
struct Index {
  @State currentIndex: number = 0;
  tabList: {
    name: string,
    unselected_icon: Resource,
    selected_icon: Resource
  }[] =
    [
      { name: "发现", unselected_icon: $r("app.media.found_unselect"), selected_icon: $r("app.media.found_select"), },
      { name: "我的", unselected_icon: $r("app.media.mine_unselect"), selected_icon: $r("app.media.mine_select") }
    ]
​
  @Builder
  TabBuilder(title: string, targetIndex: number, selectedImg: Resource, normalImg: Resource) {
    Column() {
      Image(this.currentIndex === targetIndex ? selectedImg : normalImg)
        .size({ width: 25, height: 25 })
      Text(title)
        .margin({ top: 5 })
        .fontSize(16)
        .fontColor(this.currentIndex === targetIndex ? '#FFAA00' : '#3A9B78')
    }
    .width('100%')
    .height(50)
    .justifyContent(FlexAlign.Center)
  }
​
  build() {
    Tabs({ barPosition: BarPosition.End }) {
      ForEach(this.tabList, (item: any, index: number) => {
        TabContent() {
          Text(`这个是${item.name}`)
        }.tabBar(this.TabBuilder(item.name, index, item.selected_icon, item.unselected_icon)).backgroundColor("#ccc")
      })
    }.width("100%").height("100%").onChange((index) => {
      this.currentIndex = index
    })
  }
}
​

ForEach的使用并不复杂,只要知道哪个参数对应的是啥就可以了,一般我们是不需要去设置key的生成的,直接使用默认的方式,会将所有的字段都串联起来,生成一个唯一标识。

个人公众号

呜呜呜,大佬们好,我又来求关注了,公众号求大佬们关注,谢谢

公众号文章链接

原文链接:https://juejin.cn/post/7317467562879205410 作者:做全栈开发的前端开发搬砖林小白

(0)
上一篇 2023年12月28日 下午4:02
下一篇 2023年12月28日 下午4:13

相关推荐

发表回复

登录后才能评论