itemGenerator的函数体必须使用大括号{...}。itemGenerator每次迭代只能并且必须生成一个子组件。itemGenerator中可以使用if语句,但是必须保证if语句每个分支都会创建一个相同类型的子组件。itemGenerator中不允许使用ForEach和LazyForEach语句。
赞
踩
ArkTS 提供了渲染控制的能力。条件渲染可根据应用的不同状态,使用 if、else 和 else if 渲染对应状态下的 UI 内容。
写法和 TS 的一样,简单看一下即可
@Entry @Component struct IfForEach { @State status: boolean = true build() { Row() { Column() { Button('按钮') .fontSize(30) .width(150) .height(50) .onClick(() => { this.status = !this.status; }) if (this.status) { if_son({ content: 'Southern Wind' }) } else { if_son({ content: '隐藏' }) } } .width('100%') } .height('100%') } } @Component struct if_son { content: string build() { Text(this.content) .fontSize(30) } }
效果:
另外,@State 定义的变量归父组件所有。因此,当子组件
实例被删除时,该变量不会被销毁。子组件
通过@Link装饰器
引用状态。状态必须从子级移动到其父级(或父级的父级),以避免在条件内容或重复内容被销毁时丢失状态。
例:
@Entry @Component struct CompA { @State toggle: boolean = false; @State toggleColor: boolean = false; build() { Column() { Divider().margin(20) if (this.toggle) { Text('第一个状态为true').margin(10) .backgroundColor('#aaffaa').fontSize(20) // 内部if语句 if (this.toggleColor) { Text('两个状态都为true').margin(10) .backgroundColor('#00aaaa').fontSize(15) } else { Text('第一个状态为true第二个状态为false').margin(10) .backgroundColor('#aaaaff').fontSize(15) } } else { Text('第一个状态为false').fontSize(20).margin(10) .backgroundColor('#ffaaaa') if (this.toggleColor) { Text('第一个状态为false,第二个状态为true').margin(10) .backgroundColor('#00aaaa').fontSize(15) } else { Text('两个状态都为false').margin(10) .backgroundColor('#aaaaff').fontSize(15) } } Divider().margin(20) Button('第一个状态').margin(10) .onClick(() => { this.toggle = !this.toggle; }) Button('第二个状态') .onClick(() => { this.toggleColor = !this.toggleColor; }) } .width('100%') } }
因为他默认两个状态都为 false 触发第一个状态为false'
和两个状态都为false
文本,
一共是四种效果:
效果:
接口描述:
ForEach(
arr: any[],
itemGenerator: (item: any, index?: number) => void,
keyGenerator?: (item: any, index?: number) => string
)
第一个参数为数组,允许设置为空数组,空数组场景下将不会创建子组件。
第二个参数其实就是生成遍历出来的元素和索引值,和 js 中 forEach 用法一致,只是写法略微改动。
第三个参数为匿名函数。用于给数组中的每一个数据项生成唯一且固定的键值。键值生成器的功能是可选的,但是,为了使开发框架能够更好地识别数组更改,提高性能,建议提供。如将数组反向时,如果没有提供键值生成器,则 ForEach 中的所有节点都将重建。其实也就是 vue 中 for 循环的唯一键值 key,等同于:key="item.id"
或者:key="index"
@Entry @Component struct ForEachPage { @State message: string = 'Hello World' @State flag: boolean |string = false @State arr: Array<object> = [ { id: 1, name: 'ArkTS', }, { id: 2, name: 'HTML' }, { id: 3, name: 'CSS', }, { id: 4, name: 'Javascript' }, { id: 5, name: 'PHP' } , { id: 6, name: 'WebGL' }, { id: 7, name: 'Node' }, { id: 8, name: 'Go' }, { id: 9, name: 'Vue' }, { id: 10, name: 'react' }, { id: 11, name: 'IOS' }, { id: 12, name: 'Southern Wind' }, ] build() { Row() { Column() { Text(this.message).fontSize(50) Button('取反').onClick(()=>{ this.flag=!this.flag; console.log(`${this.flag}`) }) Divider().margin(10) List({ space: 30 }) { if (this.flag){ ForEach(this.arr, (item, key) => { ListItem() { Text(`name:${item.name} --id:${item.id} -- key:${key}`) .fontSize(30) .textAlign(TextAlign.Center) .width('100%') .lineHeight(45) .backgroundColor('#bbb') } }, item => item) } }.width('100%').height('80%') }.padding(20) .width('100%') } } }
效果:
如果渲染长列表的话需要使用List
组件,不然数组数据多的情况下滚动会出现问题。
LazyForEach 就是滚动到视口的位置是才会加载,比如加载长列表图片,刚开始只渲染视口的数据,当往下拖动时才继续加载列表数据。
LazyForEach(
dataSource: IDataSource, // 需要进行数据迭代的数据源
itemGenerator: (item: any) => void, // 子组件生成函数
keyGenerator?: (item: any) => string // (可选) .键值生成函数
): void
官方的表格大家可以看一下具体参数名和描述
参数名 | 参数类型 | 必填 | 参数描述 |
---|---|---|---|
dataSource | 是 | LazyForEach数据源,需要开发者实现相关接口。 | |
itemGenerator | (item: any) => void | 是 | 子组件生成函数,为数组中的每一个数据项创建一个子组件。
说明
itemGenerator的函数体必须使用大括号{...}。itemGenerator每次迭代只能并且必须生成一个子组件。itemGenerator中可以使用if语句,但是必须保证if语句每个分支都会创建一个相同类型的子组件。itemGenerator中不允许使用ForEach和LazyForEach语句。 |
keyGenerator | (item: any) => string | 否 | 键值生成函数,用于给数据源中的每一个数据项生成唯一且固定的键值。当数据项在数组中的位置更改时,其键值不得更改,当数组中的数据项被新项替换时,被替换项的键值和新项的键值必须不同。键值生成器的功能是可选的,但是,为了使开发框架能够更好地识别数组更改,提高性能,建议提供。如将数组反向时,如果没有提供键值生成器,则LazyForEach中的所有节点都将重建。
说明
数据源中的每一个数据项生成的键值不能重复。 |
关于第一个参数IDataSource
也有详细的说明
interface IDataSource {
totalCount(): number; // 获得数据总数
getData(index: number): any; // 获取索引值对应的数据
registerDataChangeListener(listener: DataChangeListener): void; // 注册数据改变的监听器
unregisterDataChangeListener(listener: DataChangeListener): void; // 注销数据改变的监听器
}
关于事件DataChangeListener
interface DataChangeListener {
onDataReloaded(): void; // 重新加载数据时调用
onDataAdded(index: number): void; // 添加数据时调用
onDataMoved(from: number, to: number): void; // 数据移动起始位置与数据移动目标位置交换时调用
onDataDeleted(index: number): void; // 删除数据时调用
onDataChanged(index: number): void; // 改变数据时调用
onDataAdd(index: number): void; // 添加数据时调用
onDataMove(from: number, to: number): void; // 数据移动起始位置与数据移动目标位置交换时调用
onDataDelete(index: number): void; // 删除数据时调用
onDataChange(index: number): void; // 改变数据时调用
}
具体代码可以参考HarmonyOS——LazyForEach
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。