2025鸿蒙HarmonyOS开发新手入门:零基础30分钟快速上手指南

作者简介:鸿蒙应用开发者高级认证持有者,专注于HarmonyOS生态开发。本文旨在帮助零基础开发者快速入门鸿蒙应用开发,30分钟带你掌握核心概念和基础操作。本教程皆在讲述代码部分,不包含软件下载、环境配置。



一、认识HarmonyOS:为什么要学鸿蒙?

1.1 什么是HarmonyOS?

HarmonyOS(鸿蒙操作系统) 是华为自主研发的全场景分布式操作系统。它不仅仅是一个手机操作系统,而是能够运行在多种终端设备上的统一平台。

简单来说,就是一次开发,多端部署。你写一套代码,就能同时在手机、平板、手表、电视、车机等设备上运行,这就是鸿蒙的强大之处!

2025年最新动态:HarmonyOS NEXT(纯血鸿蒙)已正式发布,这是一个完全独立于Android的操作系统,仅支持鸿蒙内核和鸿蒙原生应用,标志着鸿蒙生态进入全新阶段。

HarmonyOS NEXT不再兼容Android应用,这意味着市场对原生鸿蒙开发者的需求将会爆发式增长!

1.2 HarmonyOS支持的设备

HarmonyOS的应用场景非常广泛,以下是可以搭载鸿蒙系统的设备:

设备类型 具体应用 典型产品
📱 移动设备 智能手机、平板电脑 华为Mate系列、MatePad
🏠 智能家居 智能音响、智能门锁、智能家电 华为智慧屏、小艺音箱
可穿戴设备 智能手表、智能手环 华为Watch、华为Band
🚗 车载系统 车载娱乐、车载导航 问界M7车机系统
🏭 工业控制 工业自动化、机器人控制 智能制造设备

1.3 为什么现在学鸿蒙?

如果你还在犹豫是否要学习鸿蒙开发,看看这些理由:

国家政策支持:国产操作系统是国家战略级项目,政策扶持力度大
市场需求旺盛:鸿蒙设备用户量超8亿,原生应用开发需求激增
技术优势明显:分布式能力全球领先,系统流畅度超越iOS
职业前景广阔:鸿蒙开发岗位薪资普遍高20%-30%
学习成本低:如果你会TypeScript/JavaScript,上手ArkTS非常快


二、ArkTS语言:鸿蒙开发的核心

2.1 什么是ArkTS?

ArkTS(ArkType Script)是鸿蒙生态的应用开发语言。如果你学过前端,那恭喜你,学习ArkTS会非常轻松!

语言演进路线

JavaScript (JS) → TypeScript (TS) → ArkTS (eTS)

简单理解:

  • JavaScript:前端基础语言,动态类型
  • TypeScript:JS的超集,添加了类型系统
  • ArkTS:TS的超集,专为HarmonyOS优化

如果你会JavaScript或TypeScript,学习ArkTS只需要1-2天就能上手!

2.2 ArkTS的核心特点

特性 说明 优势
静态类型 对TS的动态类型施加更严格约束 编译时发现错误,减少bug
声明式UI 以更直观的方式描述界面结构 代码简洁,可读性强
状态管理 内置强大的状态管理能力 数据改变自动刷新UI
高性能 编译优化,运行效率更高 流畅度媲美原生代码
组件化开发 支持自定义组件,代码复用 提升开发效率50%+

2.3 第一个ArkTS程序:Hello World

让我们通过一个完整的示例来感受ArkTS的魅力:

@Entry
@Component
struct HelloWorld {
  // @State装饰的变量是状态变量,改变它会自动刷新UI
  @State message: string = '你好,鸿蒙!'
  @State clickCount: number = 0
  
  build() {
    // Column:垂直布局容器
    Column() {
      // 显示文本
      Text(this.message)
        .fontSize(28)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FF0000')
        .margin({ bottom: 20 })
      
      // 显示点击次数
      Text(`点击次数:${this.clickCount}`)
        .fontSize(18)
        .fontColor('#666666')
        .margin({ bottom: 30 })
      
      // 按钮组件
      Button('点击我')
        .width(200)
        .height(50)
        .fontSize(18)
        .onClick(() => {
          // 点击时改变状态,UI会自动更新
          this.message = '欢迎来到鸿蒙世界!'
          this.clickCount++
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .backgroundColor('#F0F0F0')
  }
}

运行效果

  • 页面中央显示红色大字"你好,鸿蒙!"
  • 下方显示"点击次数:0"
  • 点击按钮后,文字变为"欢迎来到鸿蒙世界!",计数器增加

代码详解

代码部分 作用 说明
@Entry 标记入口组件 应用启动时的首页
@Component 声明自定义组件 表示这是一个可复用的UI组件
@State 状态变量 值改变会自动触发UI刷新
build() UI构建方法 在这里描述页面结构
Column() 垂直布局 子组件垂直排列
.onClick() 点击事件 用户点击时触发的回调函数

💡 核心理念:ArkTS采用数据驱动UI的思想,你只需要改变数据(状态),UI会自动更新


三、ArkTS项目结构与基本组成

3.1 项目目录结构详解

当你在DevEco Studio中创建一个新的鸿蒙项目后,会看到这样的目录结构:

MyHarmonyApp/                 # 项目根目录
├── entry/                    # 主应用模块(核心代码都在这里)
│   ├── src/                  # 源代码目录
│   │   └── main/
│   │       ├── ets/          # ArkTS源代码目录
│   │       │   ├── entryability/  # 应用入口能力
│   │       │   ├── pages/    # 页面文件(你的界面代码)
│   │       │   │   └── Index.ets  # 首页文件
│   │       │   └── common/   # 公共代码(可选)
│   │       ├── resources/    # 资源文件目录
│   │       │   ├── base/     # 基础资源
│   │       │   │   ├── media/     # 图片资源
│   │       │   │   ├── element/   # 字符串、颜色等
│   │       │   │   └── profile/   # 配置文件
│   │       │   ├── en_US/    # 英文资源
│   │       │   └── zh_CN/    # 中文资源
│   │       └── module.json5  # 模块配置文件
│   └── build-profile.json5   # 构建配置文件
├── oh_modules/               # 三方依赖库(类似node_modules)
├── build/                    # 编译输出目录
└── hvigorfile.ts            # 构建脚本

核心目录说明

目录/文件 作用 重要程度
📁 entry/src/main/ets/pages/ 存放页面代码 ⭐⭐⭐⭐⭐ 最常用
📁 entry/src/main/resources/ 存放图片、字符串等资源 ⭐⭐⭐⭐⭐ 最常用
📄 module.json5 模块配置文件 ⭐⭐⭐⭐ 重要
📁 oh_modules/ 第三方库 ⭐⭐⭐ 自动生成
📁 build/ 编译产物 ⭐基本上不用管

90%的时间你只需要关注pages目录和resources目录!

3.2 ArkTS代码的六大组成部分

一个完整的ArkTS页面代码包含以下6个核心部分,让我们通过一个计数器案例来理解:

// 【1】装饰器:给组件和变量添加特殊能力
@Entry        // 标记为应用入口
@Component    // 标记为自定义组件
struct CounterPage {
  
  // 【2】状态变量:数据发生变化时,UI会自动更新
  @State count: number = 0
  @State title: string = '计数器演示'
  
  // 【3】UI描述:build()方法,描述页面长什么样
  build() {
    Column({ space: 20 }) {  // space: 20 表示子元素间距20
      
      // 【4】系统组件:框架提供的基础组件
      Text(this.title)
        // 【5】属性方法:链式调用设置样式
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .fontColor('#333333')
      
      Text(`当前计数:${this.count}`)
        .fontSize(32)
        .fontColor(this.count > 0 ? '#FF0000' : '#333333')
      
      Row({ space: 15 }) {
        Button('减少')
          .width(100)
          // 【6】事件方法:响应用户操作
          .onClick(() => {
            this.count--
          })
        
        Button('增加')
          .width(100)
          .onClick(() => {
            this.count++
          })
        
        Button('重置')
          .width(100)
          .onClick(() => {
            this.count = 0
          })
      }
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .backgroundColor('#F5F5F5')
  }
}

运行效果

  • 页面显示"计数器演示"标题
  • 中间显示当前计数(计数>0时变红色)
  • 底部三个按钮:减少、增加、重置
  • 点击按钮,计数实时更新

六大要素详解

序号 要素 作用 关键点
1 装饰器 赋予类、变量特殊能力 @Entry入口、@Component组件、@State状态
2 状态变量 可响应的数据 改变后UI自动刷新
3 UI描述 build()方法 声明式描述界面结构
4 系统组件 框架内置组件 TextButtonColumnRow
5 属性方法 配置样式和属性 .fontSize().width()等,支持链式调用
6 事件方法 响应用户交互 .onClick().onChange()

装饰器定义身份 → 状态变量存储数据 → **build()**构建界面 → 系统组件搭积木 → 属性方法美化样式 → 事件方法响应交互


四、组件系统:构建UI的基石

HarmonyOS就像乐高积木一样,提供了各种各样的"UI积木块"(组件),你只需要把它们组合在一起,就能搭建出漂亮的界面!

4.1 组件五大分类

鸿蒙的UI组件按照功能分为五大类,每类都有自己的用途:

基础组件(最常用)
组件名 作用 使用场景
Text 显示文本 标题、正文、提示信息
Image 显示图片 头像、图标、横幅图
Button 按钮 提交、确认、跳转等操作
TextInput 文本输入框 用户名、密码、搜索框
Toggle 开关切换 设置项的开/关状态
Slider 滑块 音量、亮度调节
Progress 进度条 下载、加载进度
容器组件(布局必备)
组件名 作用 布局方向 使用场景
Column 垂直布局 ↓ 纵向 表单、列表
Row 水平布局 → 横向 导航栏、按钮组
Stack 层叠布局 重叠 徽章、悬浮按钮
List 列表容器 纵向滚动 新闻列表、联系人
Grid 网格布局 网格 相册、应用图标
Scroll 滚动容器 可滚动 长文章、长表单
媒体组件
  • Video:视频播放(支持本地和网络视频)
  • Audio:音频播放(背景音乐、语音)
绘制组件
  • Canvas:画布,支持自定义绘制(图表、签名)
  • Path:路径绘制(自定义形状)
  • Circle:圆形(圆形进度、装饰)
  • Rect:矩形(边框、背景)
其他组件
  • Swiper:轮播图
  • Tabs:标签页切换
  • Dialog:对话框
  • Loading:加载动画

💡 新手建议:先掌握Text、Button、Column、Row、Image这5个组件,就能做出80%的界面了!

4.2 常用组件实战:制作一个登录表单

让我们通过一个实际的登录界面案例,学习如何组合使用多个组件:

@Entry
@Component
struct LoginPage {
  @State username: string = ''
  @State password: string = ''
  @State rememberMe: boolean = false
  
  build() {
    Column({ space: 20 }) {
      // 【Logo区域】
      Image($r('app.media.logo'))
        .width(80)
        .height(80)
        .margin({ top: 60, bottom: 20 })
      
      // 【标题】
      Text('欢迎回来')
        .fontSize(28)
        .fontWeight(FontWeight.Bold)
        .fontColor('#333333')
      
      Text('请登录您的账号')
        .fontSize(16)
        .fontColor('#999999')
        .margin({ bottom: 20 })
      
      // 【用户名输入框】
      TextInput({ placeholder: '请输入用户名' })
        .width('85%')
        .height(50)
        .backgroundColor('#F5F5F5')
        .borderRadius(8)
        .onChange((value: string) => {
          this.username = value
        })
      
      // 【密码输入框】
      TextInput({ placeholder: '请输入密码' })
        .width('85%')
        .height(50)
        .type(InputType.Password)  // 密码类型
        .backgroundColor('#F5F5F5')
        .borderRadius(8)
        .onChange((value: string) => {
          this.password = value
        })
      
      // 【记住我】
      Row() {
        Toggle({ type: ToggleType.Checkbox, isOn: this.rememberMe })
          .onChange((isOn: boolean) => {
            this.rememberMe = isOn
          })
        
        Text('记住我')
          .fontSize(14)
          .fontColor('#666666')
          .margin({ left: 8 })
      }
      .width('85%')
      .margin({ top: 10 })
      
      // 【登录按钮】
      Button('登录')
        .width('85%')
        .height(50)
        .fontSize(18)
        .fontColor(Color.White)
        .backgroundColor('#007DFF')
        .borderRadius(8)
        .margin({ top: 30 })
        .onClick(() => {
          console.info(`用户名:${this.username}`)
          console.info(`密码:${this.password}`)
          console.info(`记住我:${this.rememberMe}`)
          // 这里添加登录逻辑
        })
      
      // 【忘记密码链接】
      Text('忘记密码?')
        .fontSize(14)
        .fontColor('#007DFF')
        .margin({ top: 15 })
        .onClick(() => {
          console.info('跳转到找回密码页面')
        })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#FFFFFF')
    .justifyContent(FlexAlign.Start)
  }
}

运行效果展示

  • 页面顶部显示Logo和欢迎文案
  • 两个圆角输入框(用户名和密码)
  • "记住我"复选框
  • 蓝色大按钮"登录"
  • 底部"忘记密码"链接

知识点总结

知识点 代码示例 说明
输入框监听 .onChange((value) => {}) 实时获取用户输入
密码类型 .type(InputType.Password) 输入内容显示为圆点
复选框 Toggle({ type: ToggleType.Checkbox }) 开关类组件
百分比宽度 .width('85%') 相对于父容器的宽度
圆角 .borderRadius(8) 数字越大越圆
垂直居中 .justifyContent(FlexAlign.Start) 控制子元素对齐方式

设计技巧:统一使用85%宽度、8圆角、#F5F5F5背景色,让界面看起来更协调!


五、生命周期管理

生命周期是应用/页面/组件从创建到销毁的整个过程。掌握生命周期有助于在合适的时机执行操作。

5.1 应用生命周期

import AbilityStage from '@ohos.app.ability.AbilityStage'

export default class MyAbilityStage extends AbilityStage {
  onCreate(): void {
    // 应用首次启动时调用
    console.info('应用启动')
  }
  
  onDestroy(): void {
    // 应用销毁时调用
    console.info('应用销毁')
  }
}

5.2 页面生命周期

@Entry
@Component
struct PageLifecycle {
  onPageShow(): void {
    // 页面每次显示时触发
    console.info('页面显示')
  }
  
  onPageHide(): void {
    // 页面每次隐藏时触发
    console.info('页面隐藏')
  }
  
  onBackPress(): boolean {
    // 当用户点击返回按钮时触发
    console.info('返回按钮被点击')
    return false  // false表示不拦截返回操作
  }
  
  build() {
    Column() {
      Text('页面生命周期演示')
    }
  }
}

5.3 组件生命周期

@Component
struct ComponentLifecycle {
  aboutToAppear(): void {
    // 组件即将出现时回调该接口,在build()之前调用
    console.info('组件创建')
  }
  
  aboutToDisappear(): void {
    // 组件即将销毁时回调该接口
    console.info('组件销毁')
  }
  
  build() {
    Text('组件生命周期演示')
  }
}

生命周期使用场景

  • aboutToAppear:初始化组件数据、订阅事件
  • onPageShow:刷新页面数据、启动定时器
  • onPageHide:暂停播放、保存状态
  • aboutToDisappear:释放资源、取消订阅、清理定时器

六、条件渲染与列表渲染

6.1 条件渲染

根据条件动态显示不同的UI内容。

@Entry
@Component
struct ConditionalRender {
  @State isLogin: boolean = false
  
  build() {
    Column({ space: 20 }) {
      // if-else 条件渲染
      if (this.isLogin) {
        Text('欢迎回来!')
          .fontSize(20)
      } else {
        Text('请先登录')
          .fontSize(20)
          .fontColor(Color.Gray)
      }
      
      Button(this.isLogin ? '退出' : '登录')
        .onClick(() => {
          this.isLogin = !this.isLogin
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

6.2 列表渲染

使用 ForEach 遍历数组,批量生成UI组件。

@Entry
@Component
struct ListRender {
  @State fruits: string[] = ['苹果', '香蕉', '橙子', '草莓', '葡萄']
  
  build() {
    Column() {
      Text('水果列表')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
        .margin({ bottom: 10 })
      
      // ForEach 列表渲染
      ForEach(this.fruits, (item: string, index: number) => {
        Row() {
          Text(`${index + 1}. ${item}`)
            .fontSize(18)
        }
        .width('90%')
        .height(50)
        .backgroundColor(Color.White)
        .borderRadius(8)
        .padding({ left: 15 })
        .margin({ bottom: 8 })
      }, (item: string) => item)  // 第三个参数是键生成函数,用于优化性能
    }
    .width('100%')
    .padding(20)
    .backgroundColor('#F5F5F5')
  }
}

七、Image图片组件详解

Image组件是显示图片的核心组件,支持多种资源类型。

7.1 加载网络资源

Image('https://example.com/image.jpg')
  .width(200)
  .height(200)

7.2 加载本地资源

将图片放在 entry/src/main/resources/rawfile/ 目录下:

Image($rawfile('local_image.png'))
  .width(200)
  .height(200)

7.3 加载Resource资源

将图片放在 entry/src/main/resources/base/media/ 目录下:

Image($r('app.media.icon'))
  .width(100)
  .height(100)
  .objectFit(ImageFit.Cover)  // 图片填充模式

7.4 Image组件完整示例

@Entry
@Component
struct ImageDemo {
  build() {
    Column({ space: 15 }) {
      Text('图片组件演示')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
      
      // 网络图片
      Image('https://picsum.photos/200')
        .width(200)
        .height(200)
        .borderRadius(10)
      
      // 本地资源
      Image($r('app.media.icon'))
        .width(100)
        .height(100)
        .interpolation(ImageInterpolation.High)  // 高质量插值
    }
    .width('100%')
    .padding(20)
  }
}

八、页面路由与导航

路由(Router)用于在不同页面之间跳转和传递数据。

8.1 路由跳转

步骤1:创建第二个页面 SecondPage.ets

// SecondPage.ets
@Entry
@Component
struct SecondPage {
  build() {
    Column() {
      Text('这是第二个页面')
        .fontSize(24)
    }
    .width('100%')
    .height('100%')
  }
}

步骤2:在首页实现跳转

import router from '@ohos.router'

@Entry
@Component
struct IndexPage {
  build() {
    Column() {
      Button('跳转到第二页')
        .onClick(() => {
          router.pushUrl({
            url: 'pages/SecondPage'  // 注意:url路径不需要加.ets后缀
          }).catch((err: Error) => {
            console.error(`路由跳转失败: ${err.message}`)
          })
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

8.2 路由跳转传值

发送数据

Button('跳转并传递数据')
  .onClick(() => {
    router.pushUrl({
      url: 'pages/DetailPage',
      params: {
        id: 100,
        name: '鸿蒙开发'
      }
    })
  })

接收数据

import router from '@ohos.router'

@Entry
@Component
struct DetailPage {
  @State id: number = 0
  @State name: string = ''
  
  aboutToAppear(): void {
    // 获取传递的参数
    const params = router.getParams() as Record<string, Object>
    this.id = params['id'] as number
    this.name = params['name'] as string
  }
  
  build() {
    Column() {
      Text(`ID: ${this.id}`)
        .fontSize(20)
        .margin({ bottom: 10 })
      Text(`名称: ${this.name}`)
        .fontSize(20)
    }
    .width('100%')
    .height('100%')
    .padding(20)
  }
}

8.3 页面返回

Button('返回上一页')
  .onClick(() => {
    router.back()  // 返回上一页
  })

九、自定义组件开发

自定义组件可以提高代码复用性和可维护性。

9.1 自定义组件基本结构

@Component
struct CustomCard {
  // 通过 @Prop 接收外部传入的参数(单向同步)
  @Prop title: string = ''
  @Prop content: string = ''
  
  build() {
    Column() {
      Text(this.title)
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .fontColor('#333333')
      
      Text(this.content)
        .fontSize(16)
        .fontColor(Color.Gray)
        .margin({ top: 8 })
    }
    .width('100%')
    .padding(15)
    .backgroundColor(Color.White)
    .borderRadius(10)
    .shadow({ radius: 4, color: '#00000020', offsetX: 0, offsetY: 2 })
  }
}

9.2 使用自定义组件

@Entry
@Component
struct HomePage {
  build() {
    Column({ space: 10 }) {
      // 使用自定义组件
      CustomCard({ 
        title: '鸿蒙开发', 
        content: '这是一个自定义卡片组件' 
      })
      
      CustomCard({ 
        title: 'ArkTS语言', 
        content: 'TypeScript的超集' 
      })
    }
    .padding(15)
  }
}

9.3 带事件的自定义组件

@Component
struct CustomButton {
  @Prop text: string = '按钮'
  // 使用函数类型定义事件回调
  onClickHandler: () => void = () => {}
  
  build() {
    Button(this.text)
      .width('90%')
      .height(45)
      .fontSize(18)
      .backgroundColor('#007DFF')
      .borderRadius(8)
      .onClick(() => {
        // 调用传入的事件处理函数
        this.onClickHandler()
      })
  }
}

// 使用示例
@Entry
@Component
struct TestPage {
  @State clickCount: number = 0
  
  build() {
    Column({ space: 15 }) {
      Text(`点击次数:${this.clickCount}`)
        .fontSize(20)
      
      CustomButton({ 
        text: '自定义按钮',
        onClickHandler: () => {
          this.clickCount++
          console.info('按钮被点击了!')
        }
      })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .padding(20)
  }
}

🔗 参考资料

本文内容基于华为官方文档编写,确保技术准确性:


作者寄语:鸿蒙开发的学习之路并不难,关键在于持续实践。作者个人认为这种同生态是未来的趋势,希望这篇文章能帮助你迈出鸿蒙开发的第一步,未来我们一起见证鸿蒙生态的蓬勃发展!

如果本文对你有帮助,欢迎点赞👍、收藏⭐、关注➕,你的支持是我创作的最大动力!
这个链接是我参与鸿蒙培训的班级链接,该活动由鸿蒙官方组织。如果你感兴趣,可以进入班级一起学习。(https://developer.huawei.com/consumer/cn/training/classDetail/ffcb0f4a66a44a3f870797de8f4faa9b?type=1?ha_source=hmosclass&ha_sourceId=89000248)


标签#HarmonyOS #鸿蒙开发 #ArkTS #零基础教程 #新手入门 #2025最新

版权声明:本文为作者原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐