博客 / 詳情

返回

鴻蒙 ArkTS 入門教程:小白實戰 List 列表開發(詳解 @State, ForEach, @Builder)

@[toc]

鴻蒙 ArkTS 入門教程:小白實戰 List 列表開發(詳解 @State, ForEach, @Builder)

摘要: 本文是一篇鴻蒙 ArkTS 小白入門教程。通過一個“國風”商品列表 Demo,帶你實戰學習 ArkTS 的 List 列表、ForEach 循環、@State 狀態管理和 @Builder 自定義組件。從零開始,快速掌握鴻蒙列表頁面的開發核心。

Hello 大家好!剛開始學鴻蒙(HarmonyOS)開發,是不是感覺 ArkTS 有點東西?別怕,今天我(一個和你一樣剛起步的萌新)就來分享一下我的學習 Demo 筆記——一個看起來“高大上”的中國傳統文化商品展示頁!

別看它長得復古,用的知識點可都是“潮牌”:List 列表ForEach 循環@State 狀態管理@Builder 自定義組件

別看名詞多,其實捅破了就那層窗户紙!上車,出發!

STEP 1: “兵馬未動,糧草先行”——定義數據模型

在寫界面之前,我們得先告訴程序,咱們的“商品”長啥樣。總不能空手套白狼吧?

咱們先用 class 定義一個 CultureProduct(文化產品)類。它就像一個商品説明書模板,規定了每個商品必須有 ID、名字、價格、表情包(bushi,是 emoji 圖標)、描述和分類。這就是咱們的數據結構。

// 中國傳統文化商品展示 Demo
// 知識點:List列表、ForEach循環、@State狀態管理、自定義組件

// 商品數據模型
class CultureProduct {
  id: number;
  name: string;
  price: number;
  emoji: string;
  description: string;
  category: string;

  constructor(id: number, name: string, price: number, emoji: string, description: string, category: string) {
    this.id = id;
    this.name = name;
    this.price = price;
    this.emoji = emoji;
    this.description = description;
    this.category = category;
  }
}
````

## STEP 2: 開張!創建頁面和“魔法”狀態

![](https://files.mdnice.com/user/139748/2b643e51-70de-4735-90f2-f0cea5cbb8dd.png)

有了模板,咱們就該創建頁面(`@Component`)了。`@Entry` 告訴系統:“嘿,這就是我的店門面,程序從這裏啓動!”

最關鍵的來了:`@State` 裝飾器。這玩意兒是鴻蒙 ArkTS 的“響應式魔法”之一。

用 `@State` 標記的 `productList`(我們的商品列表)一旦發生變化(比如你以後做了個“添加商品”按鈕),UI 界面就會**自動刷新**!再也不用手動操作 DOM 了,是不是很爽?

我們先“偽造”一點數據,把 `productList` 填滿,開張大吉!

@Entry
@Component
export struct CultureProductDemo {
  // 商品列表數據
  @State productList: CultureProduct[] = [
    new CultureProduct(1, '青花瓷茶具', 688, '🫖', '景德鎮手工青花瓷,傳承千年工藝', '茶具'),
    new CultureProduct(2, '宣紙書法套裝', 298, '📜', '安徽宣紙,配毛筆墨汁,初學者首選', '文房四寶'),
    new CultureProduct(3, '紫砂壺', 1280, '🍵', '宜興紫砂,純手工製作,養壺佳品', '茶具'),
    new CultureProduct(4, '中國結掛飾', 88, '🪢', '手工編織,寓意吉祥如意', '裝飾品'),
    new CultureProduct(5, '古琴', 3800, '🎵', '桐木古琴,音色悠揚,附贈教學視頻', '樂器'),
    new CultureProduct(6, '景泰藍花瓶', 1580, '🏺', '北京景泰藍,宮廷工藝,收藏佳品', '工藝品'),
    new CultureProduct(7, '漢服套裝', 568, '👘', '明制漢服,刺繡精美,含配飾', '服飾'),
    new CultureProduct(8, '圍棋套裝', 428, '⚫', '雲子圍棋,實木棋盤,適合對弈', '棋類')
  ];


## STEP 3: 搭建“貨架”——佈局和標題

![](https://files.mdnice.com/user/139748/0b6beab2-a8cf-498c-be2b-a21bee6d6ac8.png)

數據有了,咱得搭個貨架(頁面佈局)。

每個組件都有一個 `build()` 方法,這是它的“化妝間”,負責畫出它的樣子。我們先放一個 `Column()`,意思是裏面的東西都給我**垂直排好隊**。

然後加個 `Text()` 標題,調調字號、加粗、顏色啥的,讓它看起來像個“標題黨”,專業!

  build() {
    Column() {
      // 頁面標題
      Text('傳統文化精品')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .fontColor('#8B4513')
        .margin({ top: 20, bottom: 16 })


## STEP 4: 循環“上貨”—— List 和 ForEach 閃亮登場

![](https://files.mdnice.com/user/139748/5a50e1df-ad64-45a5-aff4-0666c3f35c6a.png)

重點來了!我們怎麼把 `@State` 裏的那一堆商品數據(`productList`)一個個擺到“貨架”上?

答案是 `List` + `ForEach` 這對黃金搭檔!

  * `List`: 顧名思義,就是個列表容器,自帶“滾動”技能。
  * `ForEach`: 這就是個“循環打印機”。它會遍歷 `productList` 裏的**每一項**(我們臨時叫它 `product`),然後為每一項執行一次 `ListItem()` 裏的操作。

在 `ListItem()` 裏面,我們沒有直接寫一堆 `Row`、`Column`,而是調用了一個**自定義組件**:`this.ProductCard(product)`。

這就像在説:“嘿,`ProductCard` 小弟(我們待會兒就定義它),這個 `product` 數據給你,你幫我把它畫成一個卡片的樣子!”

(`layoutWeight(1)` 是個小技巧,意思是讓列表佔滿 `Column` 裏的剩餘所有空間。)

      // 商品列表
      List({ space: 12 }) {
        ForEach(this.productList, (product: CultureProduct) => {
          ListItem() {
            this.ProductCard(product)
          }
        }, (product: CultureProduct) => product.id.toString())
      }
      .width('100%')
      .layoutWeight(1)
      .backgroundColor('#FFF8DC')
    }
    .width('100%')
    .height('100%')
    .padding({ left: 16, right: 16 })
    .backgroundColor('#FFFAF0')
  }


## STEP 5: “私人訂製”—— @Builder 自定義卡片組件

![](https://files.mdnice.com/user/139748/51cbe3a5-3f25-4463-a52b-b3fbb1c9012f.png)

終於到了我們的大功臣——`ProductCard` 卡片組件!

這裏用到了 `@Builder` 裝飾器。你可以把它理解為一個“UI 藍圖生成器”。它是一個方法,你給它一個 `product` 數據,它就還你一個畫好的 UI 組件。

這樣做的好處是**代碼複用**和**結構清晰**!如果以後想改卡片樣式,只需要改這一個地方,`List` 裏的所有卡片都會跟着變。

卡片內部,我們用一個 `Row()`(水平佈局)分成了左右兩部分。

  // 商品卡片組件
  @Builder
  ProductCard(product: CultureProduct) {
    Row() {


### 5.1 卡片左側:圖標和分類

![](https://files.mdnice.com/user/139748/fe2f9e8a-2847-43f5-9f04-6b85cb9f6026.png)

左邊是一個 `Column()`(垂直佈局),放“表情包” `emoji` 和一個帶背景色的 `category` 分類標籤。調調間距和背景,小小的細節,瞬間提升 B 格。

      // 左側:商品圖標和分類
      Column() {
        Text(product.emoji)
          .fontSize(40)
        Text(product.category)
          .fontSize(10)
          .fontColor('#FFFFFF')
          .backgroundColor('#D2691E')
          .borderRadius(4)
          .padding({ left: 6, right: 6, top: 2, bottom: 2 })
          .margin({ top: 4 })
      }
      .width(80)
      .height(80)
      .justifyContent(FlexAlign.Center)
      .backgroundColor('#FFF5EE')
      .borderRadius(8)


### 5.2 卡片右側:名稱、價格和描述

![](https://files.mdnice.com/user/139748/cbd0b734-31c7-4d83-8ea0-f7eacb3a7ae4.png)

右邊也是一個 `Column()`(垂直佈局),用來放商品信息。

  * **第一行**:我們又用了一個 `Row()`(水平佈局),左邊放商品名稱 `name`(`layoutWeight(1)` 讓它搶佔所有剩餘空間),右邊放價格 `price`。
  * **第二行**:放商品描述 `description`。注意 `maxLines(2)` 和 `textOverflow({ overflow: TextOverflow.Ellipsis })`,這是防止描述太長“溢出”的經典操作,多餘的字會變成“...”。

<!-- end list -->

      // 右側:商品信息
      Column() {
        // 商品名稱和價格
        Row() {
          Text(product.name)
            .fontSize(16)
            .fontWeight(FontWeight.Medium)
            .fontColor('#8B4513')
            .layoutWeight(1)
          Text('¥' + product.price)
            .fontSize(18)
            .fontWeight(FontWeight.Bold)
            .fontColor('#DC143C')
        }
        .width('100%')
        .margin({ bottom: 8 })

        // 商品描述
        Text(product.description)
          .fontSize(14)
          .fontColor('#A0522D')
          .maxLines(2)
          .textOverflow({ overflow: TextOverflow.Ellipsis })
      }
      .layoutWeight(1)
      .padding({ left: 12 })
      .alignItems(HorizontalAlign.Start)


### 5.3 收尾:卡片樣式和點擊事件

![](https://files.mdnice.com/user/139748/d532289c-2daa-4fa9-bc0a-e10df8ce2a14.png)

最後,我們給最外層的 `Row()`(也就是整個卡片)加上圓角、背景色、陰影(`shadow` 讓它有“浮”起來的立體感),還有最重要的 `onClick` 點擊事件!

現在,你點擊任何一個商品卡片,控制枱(Console)都會打印出你點擊了誰。這就是交互的起點!

    }
    .width('100%')
    .padding(12)
    .backgroundColor('#FFFFFF')
    .borderRadius(12)
    .shadow({ radius: 8, color: '#E0E0E0', offsetX: 0, offsetY: 2 })
    .onClick(() => {
      console.info(點擊了商品:${product.name})
    })
  }
}


## 🏁 總結:你的鴻蒙之旅已啓程

![](https://files.mdnice.com/user/139748/e4d59d57-f8d6-42cd-8bb6-58af677f597f.jpg)

恭喜你!你已經成功完成了這個“國風”商品列表。我們來快速回顧一下你解鎖的技能點:

  * **數據模型 (Class):** 搭建了應用的基礎數據骨架。
  * **@State:** 掌握了讓 UI 自動“活”起來的響應式魔法。
  * **List + ForEach:** 學會了如何高效地批量渲染數據。
  * **@Builder:** 獲得了創建可複用、高顏值 UI 模塊的技能。

這幾個知識點是 ArkTS 開發中名副其實的“基石”。

不要小看這個 Demo,你已經掌握了構建複雜列表頁面的核心邏輯。這只是一個開始,繼續保持這份好奇心,多動手實踐,從這個小小的起點出發,一步步去探索鴻蒙世界的更多可能。相信自己,你的開發之路會越走越寬廣!

-----

**文章標籤:** 鴻蒙 ArkTS @State List ForEach @Builder 鴻蒙入門


user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.