文章概叙
本文主要使用一个简单的例子介绍一下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 作者:做全栈开发的前端开发搬砖林小白