鸿蒙开发vs前端开发1-父子组件传值

1. 页面结构与多组件写法

  • 一个 .ets 文件里可以写 多个组件 :一个 @Entry 页面组件 + 若干普通子组件。
  • @Entry 有且只能有一个,表示页面入口。
  • 子组件只加 @Component,不加 @Entry

2. 响应式状态:@State

  • 作用:数据改变 → 页面自动刷新(对应 Vue 的 ref)。

  • 用法:

    css 复制代码
    @State cartCount: number = 0
  • 修改变量必须用 this.xxx,否则报错。

3. 父子组件传值(今天最重点)

① 传基础类型(string /number/boolean)

  • @Prop
  • 最简单、最安全,不会报错

② 传对象 / 复杂数据

  • 必须用:@Observed 类 + @ObjectLink

    1. 先定义被观察类:

      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
            }
      }
    2. 父组件用 new ProductItem() 创建实例

    3. 子组件用 @ObjectLink product: ProductItem 接收

③ 传函数 / 回调事件

  • 直接写函数名,不需要任何装饰器

    onAddToCart: () => void

4. 点击事件

  • 语法:.onClick(() => { })
  • 对应 Vue 的 @click,逻辑完全一样。

5. 布局与样式回顾

  • Column():垂直布局(默认从上到下)
  • Row():水平布局(默认从左到右)
  • Blank():自动撑开空白(实现左右对齐)
  • 阴影:.shadow({ radius, color, offsetX, offsetY })

6. 鸿蒙 ↔ Vue 关键区别(必记)

  1. Vue 可以直接 props 传对象,鸿蒙不行
  2. Vue 不用写 this.,鸿蒙必须写
  3. Vue 构造函数可写键值对,TS / 鸿蒙只能按顺序传参
  4. 鸿蒙对象传参强制要求 @Observed + @ObjectLink

7. 今天遇到的经典报错避坑

  1. @Prop 不支持对象 → 对象改用 @ObjectLink
  2. @ObjectLink 必须搭配 @Observed 类 → 把对象包成 class
  3. Cannot find name 'name' → 少写了 this.
  4. 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
相关推荐
卡尔特斯2 小时前
Android Studio 代理配置指南
android·前端·android studio
李剑一2 小时前
同样做缩略图,为什么别人又快又稳?踩过无数坑后,我总结出前端缩略图实战指南
前端·vue.js
Jolyne_2 小时前
Taro样式重构记录
前端
恋猫de小郭2 小时前
Google 开源大模型 Gemma4 怎么选,本地跑的话需要什么条件?
前端·人工智能·ai编程
文心快码BaiduComate2 小时前
Comate搭载GLM-5.1:长程8H,对齐Opus 4.6
前端·后端·架构
熊猫钓鱼>_>2 小时前
AI驱动的Web应用智能化:WebMCP、WebSkills与WebAgent的融合实践
前端·人工智能·ai·skill·webagent·webmcp·webskills
毛骗导演3 小时前
OpenClaw Pi Agent 深度解析:嵌入式 Agent 运行时的架构设计与实现
前端·架构
twl3 小时前
从 RAG 到可持续演化的知识库:llm-wiki 介绍
前端