鸿蒙开发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
相关推荐
前端若水17 小时前
技术选型:React 19 + TypeScript + TailwindCSS
前端·react.js·typescript
木斯佳17 小时前
前端八股文面经大全:携程前端暑期实习一面(2026-05-14)·面经深度解析
前端
卸任17 小时前
为Tiptap富文本编辑器增加导出PDF功能
前端·react.js
ZC跨境爬虫17 小时前
跟着 MDN 学CSS day_1:(CSS 基石与色彩的艺术)
前端·javascript·css·ui·html
NiceCloud喜云17 小时前
Claude API 流式输出(SSE)实战:从打字机效果到工具调用全流程
java·前端·ide·人工智能·chrome·intellij-idea·状态模式
青春喂了后端17 小时前
IntelliGit 前端入口与开发测试面板边界重构
前端·重构
广州灵眸科技有限公司18 小时前
瑞芯微(EASY EAI)RV1126B 千兆以太网电路
服务器·前端·人工智能·python·深度学习
梦想的旅途218 小时前
基于 RPA 自动化技术的外部群主动消息推送实现指南
前端·自动化·rpa
jiayong2318 小时前
前端面试题库 - React框架篇
前端·javascript·react.js
ttwuai18 小时前
XYGo Admin 国际化实战:Vue3 中后台多语言方案详解
前端·javascript·vue.js·vue