1. 页面结构与多组件写法
- 一个
.ets文件里可以写 多个组件 :一个@Entry页面组件 + 若干普通子组件。 @Entry有且只能有一个,表示页面入口。- 子组件只加
@Component,不加@Entry。
2. 响应式状态:@State
-
作用:数据改变 → 页面自动刷新(对应 Vue 的
ref)。 -
用法:
css@State cartCount: number = 0 -
修改变量必须用
this.xxx,否则报错。
3. 父子组件传值(今天最重点)
① 传基础类型(string /number/boolean)
- 用
@Prop - 最简单、最安全,不会报错
② 传对象 / 复杂数据
-
必须用:
@Observed类 +@ObjectLink-
先定义被观察类:
ts
typescript@Observed class ProductItem { name: string; price: number; image: string constructor(name: string, price: number, image: string) { this.name = name; this.price = price; this.image = image } } -
父组件用
new ProductItem()创建实例 -
子组件用
@ObjectLink product: ProductItem接收
-
③ 传函数 / 回调事件
-
直接写函数名,不需要任何装饰器
onAddToCart: () => void
4. 点击事件
- 语法:
.onClick(() => { }) - 对应 Vue 的
@click,逻辑完全一样。
5. 布局与样式回顾
Column():垂直布局(默认从上到下)Row():水平布局(默认从左到右)Blank():自动撑开空白(实现左右对齐)- 阴影:
.shadow({ radius, color, offsetX, offsetY })
6. 鸿蒙 ↔ Vue 关键区别(必记)
- Vue 可以直接
props传对象,鸿蒙不行 - Vue 不用写
this.,鸿蒙必须写 - Vue 构造函数可写键值对,TS / 鸿蒙只能按顺序传参
- 鸿蒙对象传参强制要求
@Observed+@ObjectLink
7. 今天遇到的经典报错避坑
@Prop 不支持对象→ 对象改用@ObjectLink@ObjectLink 必须搭配 @Observed 类→ 把对象包成 classCannot find name 'name'→ 少写了this.new 构造函数不能写 key:value→ 直接按顺序传参
示例代码
less
@Observed
class ProductItem {
name: string;
price: number;
image: string
constructor(name: string, price: number, image: string) {
this.name = name;
this.price = price;
this.image = image
}
}
@Component
struct ProductCard {
@ObjectLink product: ProductItem
onAddToCart: () => void
build() {
Column() {
Image(this.product.image)
.width(200)
.height(200)
.objectFit(ImageFit.Contain)
.margin({ bottom: 15 })
Text(this.product.name)
.fontSize(20)
.fontWeight(FontWeight.Medium)
.margin({ bottom: 10 })
Text(`¥${this.product.price}`)
.fontSize(24)
.fontColor('#ff6600')
.fontWeight(FontWeight.Bold)
Button('加入购物车')
.width('100%')
.height(45)
.onClick(() => {
this.onAddToCart()
})
}
.width('90%')
.padding(20)
.backgroundColor('#fff')
.borderRadius(16)
.shadow({
color: '#ddd',
radius: 8,
offsetX: 2,
offsetY: 2
})
}
}
@Entry
@Component
struct IndexDemo {
@State cartCount: number = 0
@State product: ProductItem = new ProductItem(
"鸿蒙开发学习",
100,
"https://res2.vmallres.com/pimages/uomcdn/CN/pms/202403/gbom/6942103109560/428_428_9D3B788CDF5A83F6820BCA9411A6899Dmp.png"
)
build() {
Column() {
Row() {
Text("极简购物商城")
.fontSize(24)
.fontWeight(FontWeight.Bold)
Blank()
Text(`购物车:${this.cartCount}`)
.fontSize(18)
.fontColor('#ff6600')
}
.width('100%')
.padding({ left: 20, right: 20, top: 20, bottom: 20 })
ProductCard({
product: this.product,
onAddToCart: () => {
this.cartCount++
}
})
.margin({ top: 20 })
}
.width("100%")
.height("100%")
.backgroundColor("#f2f3f5")
}
}
export default IndexDemo