1.1、定义 model 数据模型
class FoodItem { //导出认为这个不存在, export表示这个类被别人引用
id:number = 0
name:string = ''
like_rate_desc = ''
month_saled:number = 0
unit:string = ''
food_tag_list:string[] = []
price:number = 0
picture:string = ''
description:string = ''
tag:string = ''
count:number = 0
}
// 定义class类型
class Category {
tag:string = ''
name:string = ''
foods:FoodItem[] = []
}
1.2、使用 http 发送请求,获取数据
import http from '@ohos.net.http'
@Entry
@Component
struct MeiTuan {
@State list:Category[] = [] // 生命数据结构
// 获取数据,将数据动态渲染
aboutToAppear() { // 在组件初始化之后,在build之前去执行,只会执行一次
// 获取美团餐饮数据
this.getMTData()
}
async getMTData() {
try {
const req = http.createHttp()
const res =await req.request("https://zhoushugang.gitee.io/fe2022/takeaway.json")
this.list = JSON.parse(res.result as string) as Category[]
// AlertDialog.show({message:this.list.length.toString()})
} catch(e) {
}
}
@State showCart:boolean = false
build() {
Stack({alignContent:Alignment.Bottom}) {
// 主内容组件
MTMain({list:$list})
if (this.showCart) {
// 购物车组件
MTCart()
}
// 底部组件
MTBottom({showCart:$showCart})
}.height('100%')
}
}
1.3、主体组件
// 主内容区组件
@Component
struct MTMain {
@Link list:Category[]
@State selectIndex:number = 0
build() {
Column() {
MTNav()
// 左侧是分类,右侧是菜品的结构
Row() {
// 左侧分类
// 条件渲染不能用三元表达式-条件渲染:创建和销毁元素
Column() {
ForEach(this.list,(item:Category, index:number)=>{
Text(item.name)
.height(50)
.width('100%')
.fontSize(14)
.textAlign(TextAlign.Center)
.backgroundColor(this.selectIndex === index ? '#fff' : '#f5f5f5')
.onClick(() => {
this.selectIndex = index
})
})
}.width(90)
.height('100%')
.backgroundColor('#f5f5f5')
// 右侧内容
// 放置若干个菜品数量
List() {
// ? || 为断路表达式 this.list[this.selectIndex] 有可能为undefind,?表示如果是undefined就不取foods,取[]
ForEach(this.list[this.selectIndex]?.foods || [], (item:FoodItem) => {
ListItem() {
MTFoodItem({item:item})
}
})
}
.layoutWeight(1)
}
.width('100%')
// .justifyContent(FlexAlign.Start)
.alignItems(VerticalAlign.Top)
}
.height('100%')
.width('100%')
}
}
1.4、FoodItem组件使用属性接收数据并渲染
// 单品食物组件
@Component
struct MTFoodItem {
item:Partial<FoodItem> = {}
build() {
Row() {
Image(this.item.picture)
.width(90)
.aspectRatio(1)
Column({ space: 5 }) {
Text(this.item.name)
.textOverflow({
overflow: TextOverflow.Ellipsis,
})
.maxLines(2)
.fontWeight(600)
Text(this.item.description)
.textOverflow({
overflow: TextOverflow.Ellipsis,
})
.maxLines(1)
.fontSize(12)
.fontColor('#333')
Text(this.item.unit)
.fontSize(10)
.backgroundColor('#fff5e2')
.fontColor('#ff8000')
.padding({ top: 2, bottom: 2, right: 5, left: 5 })
.borderRadius(2)
Text() {
Span(`月销售40${this.item.month_saled}`)
Span(' ')
Span(this.item.like_rate_desc)
}
.fontSize(12)
.fontColor('#999')
Row() {
Text() {
Span('¥ ')
.fontColor('#ff8000')
.fontSize(10)
Span(this.item.price.toFixed(2))
.fontColor('#ff8000')
.fontWeight(FontWeight.Bold)
}
}
.justifyContent(FlexAlign.SpaceBetween)
.width('100%')
}
.layoutWeight(1)
.alignItems(HorizontalAlign.Start)
.padding({ left: 10, right: 10 })
}
.padding(10)
.alignItems(VerticalAlign.Top)
}
}
1.5、底部组件使用Link控制购物车显示隐藏
// 底部组件
@Component
struct MTBottom {
@Link showCart:boolean
build() {
Row() {
.onClick(() => {
this.showCart = !this.showCart
})
}
}
}
网友评论