前端开发转鸿蒙开发1-父子组件传值差异
1. 页面结构与多组件写法一个.ets文件里可以写多个组件一个Entry页面组件 若干普通子组件。Entry有且只能有一个表示页面入口。子组件只加Component不加Entry。2. 响应式状态State作用数据改变 → 页面自动刷新对应 Vue 的ref。用法State cartCount: number 0修改变量必须用this.xxx否则报错。3. 父子组件传值今天最重点① 传基础类型string /number/boolean用Prop最简单、最安全不会报错② 传对象 / 复杂数据必须用Observed类 ObjectLink先定义被观察类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: () void4. 点击事件语法.onClick(() { })对应 Vue 的click逻辑完全一样。5. 布局与样式回顾Column()垂直布局默认从上到下Row()水平布局默认从左到右Blank()自动撑开空白实现左右对齐阴影.shadow({ radius, color, offsetX, offsetY })6. 鸿蒙 ↔ Vue 关键区别必记Vue 可以直接props传对象鸿蒙不行Vue 不用写this.鸿蒙必须写Vue 构造函数可写键值对TS / 鸿蒙只能按顺序传参鸿蒙对象传参强制要求ObservedObjectLink7. 今天遇到的经典报错避坑Prop 不支持对象→ 对象改用ObjectLinkObjectLink 必须搭配 Observed 类→ 把对象包成 classCannot find name name→ 少写了this.new 构造函数不能写 key:value→ 直接按顺序传参示例代码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