需求: 创建多个列表组件,并实现点赞功能
语言: ArkTS
平台: DevEco Studio
ForEach 接口描述
ForEach(
arr: Array,
itemGenerator: (item: Object, index: number) => void,
keyGenerator?: (item: Object, index: number) => string
)
具体代码 (含注释)
//被@Observed装饰的类可以被观察到属性的变化
@Observed
class Article {
id: string;
title: string;
brief: string;
isLiked: boolean;
likesCount: number;
constructor(id: string, title: string, brief: string, isLiked: boolean, likesCount: number) {
this.id = id;
this.title = title;
this.brief = brief;
this.isLiked = isLiked;
this.likesCount = likesCount;
}
}
@Entry
@Component
struct ArticleListView {
//状态变量
@State articleList: Array<Article> = [
new Article('001', '第0篇文章', '文章简介内容', false, 100),
new Article('002', '第1篇文章', '文章简介内容', false, 100),
new Article('003', '第2篇文章', '文章简介内容', false, 100),
new Article('004', '第4篇文章', '文章简介内容', false, 100),
new Article('005', '第5篇文章', '文章简介内容', false, 100),
new Article('006', '第6篇文章', '文章简介内容', false, 100),
];
build() {
//List用于排列包含一系列相同宽度的列表项
List() {
//循环渲染
//数据项: this.articleList
//组件生成函数: ArticleCard
//键值生成函数: (item: Article) => item.id --- 传入参数为article; 将article的id属性做为键值生成规则
ForEach(this.articleList, (item: Article) => {
//ListItem()用来展示列表具体组件,必须配合List()来使用
ListItem() {
ArticleCard({
article: item
})
.margin({ top: 20 })
}
}, (item: Article) => item.id)
}
.padding(20)
.scrollBar(BarState.Off)
.backgroundColor(0xF1F3F5)
//添加滚动条
.scrollBar(BarState.On)
}
}
//子组件ArticleCard
@Component
struct ArticleCard {
//子组件中@ObjectLink装饰器装饰的状态变量用于接收@Observed装饰的类的实例,和父组件中对应的状态变量建立双向数据绑定
//若子组件中状态变量(article)的子属性发生变化,则立即同步至父组件
//ForEach检测到父组件中的状态变量的子属性发生变化后会立即触发ForEach的重新渲染
@ObjectLink article: Article;
//组件内函数,用于实现点♥的属性变化
handleLiked() {
this.article.isLiked = !this.article.isLiked;
this.article.likesCount = this.article.isLiked ? this.article.likesCount + 1 : this.article.likesCount - 1;
}
build() {
Row() {
Image($r('app.media.icon'))
.width(80)
.height(80)
.margin({ right: 20 })
Column() {
Text(this.article.title)
.fontSize(20)
.margin({ bottom: 8 })
Text(this.article.brief)
.fontSize(16)
.fontColor(Color.Gray)
.margin({ bottom: 8 })
Row() {
Image(this.article.isLiked ? $r('app.media.iconLiked') : $r('app.media.iconUnLiked'))
.width(24)
.height(24)
.margin({ right: 8 })
Text(this.article.likesCount.toString())
.fontSize(16)
}
//点击事件,调用handleLiked函数
.onClick(() => this.handleLiked())
.justifyContent(FlexAlign.Center)
}
.alignItems(HorizontalAlign.Start)
.width('80%')
.height('100%')
}
.padding(20)
.borderRadius(12)
.backgroundColor('#FFECECEC')
.height(120)
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
}
}