🚀 鸿蒙开发之旅:快速入门指南
为了开发鸿蒙应用,我同时看了 Flutter 、Swift UI、Android App Compose 开发。
因为我个人认为,需要增加鸿蒙开发的任务,至少在当下 2025 年,企业必然会先推出 iOS 和安卓应用去占领市场再推出鸿蒙。所以,我想知道经过 iOS 和安卓开发或者使用跨平台开发后能怎么帮助我们快速进行鸿蒙开发。怎么进行快速入门。
我发现移动端开发发展至今,正在逐步实现统一 ------ 声明式开发 🎉
这里说到的声明式开发,于是我开始去了解了一下发展历程。倒是一个惊人的发现:
豆包回答:
在移动端开发中,Facebook 的 React Native被认为是开启声明式开发范式潮流的重要框架。
React Native 于 2013 年开始作为 Facebook 的一个黑客马拉松项目启动。它的目标是将网页开发中备受喜爱的特性,如快速开发、即时重载和平台无关性等引入到移动端开发中,让开发者能够用很少的特定于平台的代码构建跨平台应用,实现 "一次学习,随处编写"。它基于 React 的理念,将声明式的编程风格从 Web 开发领域拓展到了移动应用开发领域,为后来的移动端声明式开发框架奠定了基础。
在 React Native 之后,Google 在 2018 年底推出了 Flutter,结合 Dart 语言引入了新的声明式开发范式,基于 Skia 的自绘制引擎构建可跨平台的独立渲染能力。2019 年,苹果推出了 SwiftUI,谷歌推出了 Jetpack Compose,这两个框架进一步推动了声明式开发在 iOS 和安卓原生开发中的应用。
这一结果侧面反映了 React Native 的成功,以及大家对声明式开发范式的挖掘不断增加。另外类似 Futter 的成功也可以说是推动了原生开发框架的进步。
所以鸿蒙的 ArkUI 无疑方向是非常正确的。 这在未来也将有利于融合到其他的开发框架中。所以我主要就看 Arkts 和 ArkUI,以及对应的 API、第三方库等内容。
🧐 文章背景与初衷
因为公司项目临时需求,原本的 APP 突然需要有一款鸿蒙平台的软件。于是我花了半天把鸿蒙捡起来。在此之前,我大概在大学时期跟老师学过一段时间鸿蒙开发,但是当时并不太懂移动端这些事情,也没有完整做出过一个能拿得出手的 APP,并且缺乏对软件项目工程化的理解。所以,之前的经验可以忽略不计,只是有了鸿蒙开发者账号而已。所以,我在 5 月底花了半天的时间,看了下鸿蒙官方文档,进行学习鸿蒙开发。所以这篇文章总结的鸿蒙开发入门也主要是从官方文档学习而来的,同时结合了自己使用 RN 移动端开发经验以及对 Flutter 和 swiftUI 的了解开始入门的。
要开始鸿蒙开发的我认为绝大多数的人都是从前端或者其他移动端开发兼容过来的。从 0 开始学的还是少数,所以我决定不拖泥带水,简单且大概率不会出错的事情我就不进行赘述了。
🛠️ 准备工作:搭建开发环境
没有什么特别需要安装的语言环境。因为我们主要面对的就是 Arkts 和 ArkUI 开发鸿蒙原生应用。所以主要有一个编辑器就可以了。目前 vscode 是不太能识别 ets 文件的,所以在 AI 编程上稍微会有点欠缺,不过毕竟是新框架,采用的也是残缺版的 ts,用 AI 编程也还是害怕会有太多坑,所以还是自己走一遍是最保险,对于后续使用 AI 开发鸿蒙应用,也是有更多好处的。所以,当下入门部分我们不会考虑借助 AI 来编程。但是使用官方 IDE 中的 Ai 进行文档搜索或者组件封装帮助倒是可以的。
所以,现在我们主要要准备的就是官方的开发编辑器:DevEco Studio-鸿蒙应用集成开发环境(IDE)-华为开发者联盟
必备神器:DevEco Studio 💎
标题已经附带了官方下载链接,可以直接点击下载。安装步骤很简单,无脑下一步就可以了。
至于主题和快捷键,我的建议是默认的就好,快捷键不用调整成 vscode,它并不 vscode。所以快捷键方案直接用原来的和 Idea/Android Studio 一样的就行了。
这里附带上这个编辑器对电脑配置的需求。

🏗️ 项目结构解析
这里我们主要看的是 Arkts 工程目录结构,其他的 C++和 JS 目录结构也可以通过官方文档进行了解:
工程目录结构-工程创建-开发环境搭建 - 华为HarmonyOS开发者

官方有的我简单拷贝一下:
AppScope > app.json5:应用的全局配置信息。
entry:
应用/元服务模块,编译构建生成一个HAP。
- src > main > ets:用于存放ArkTS源码。
- src > main > ets > entryability:应用/元服务的入口。
- src > main > ets > pages:应用/元服务包含的页面。
- **src > main > resources:**用于存放应用/元服务模块所用到的资源文件,如图形、多媒体、字符串、布局文件等。关于资源文件的详细说明请参考资源分类与访问。
- src > main > module.json5 :Stage模型模块配置文件,主要包含HAP的配置信息、应用在具体设备上的配置信息以及应用的全局配置信息。具体请参考module.json5配置文件。
- **build-profile.json5:**当前的模块信息、编译信息配置项,包括buildOption、targets配置等。
- hvigorfile.ts:模块级编译构建任务脚本。
- oh-package.json5:描述三方包的包名、版本、入口文件(类型声明文件)和依赖项等信息。
oh_modules:用于存放三方库依赖信息,包含应用/元服务所依赖的第三方库文件。
**build-profile.json5:**应用级配置信息,包括签名、产品配置等。
**hvigorfile.ts:**应用级编译构建任务脚本。
**oh-package.json5:**描述全局配置,如:依赖覆盖(overrides)、依赖关系重写(overrideDependencyMap)和参数化配置(parameterFile)等。
可以看到这里的目录结构可以说是前端、Android 项目的大杂烩。工程采用多模块的方式,我们主要是在 entry 模块下进行开发。支持用户可以创建其他模块来实现逻辑隔离和抽象。
另外,可以明显看到前端开发工程的影子:
oh_modules -> node_models: 但是这里不适用 npm 包。
oh-package.json5 -> package.json: 所以如果需要看当前项目有哪些依赖,大家可以非常习惯的找到这个文件,可以说是对前端转鸿蒙人员,除了 ts 的使用以外的仅剩的友好了。
📦 第三方库:扩展你的能力
看到这里应该会立即问:不能使用 npm 包,那么能使用的第三方库我要怎么找。说来惭愧,直到我开发完第一个鸿蒙项目后,我才终于去找了第三方库。因为原生 API 已经能满足非常多的场景需求,开发速度也确实不会慢。在学习鸿蒙半天后,接下来本来我有两周(合计 10 天的)的时间来开发,实际上我们依然早了一天完成了工作。当然,这里也有其他同事参与协助的情况下的。但他们的经验只比我少。
第三方库地址:OpenHarmony三方库中心仓
大家也可以直接通过搜索引擎搜索
鸿蒙第三方中心仓
或者鸿蒙第三方库
搜索到。like this:
我当时看完后才觉得,我们可以更快的,因为一些弹窗的封装耗费的时间完全可以被第三方库给弥补。不过也没关系,我们正常交付了。
✨ 创建你的第一个鸿蒙项目

📱 构建第一个页面
创建页面的方式是有选择的。估计有不少安卓转鸿蒙的开发者会立即注意到:

没错,这是鸿蒙早期的页面组织方式:
页面路由 (@ohos.router)(不推荐)-设置组件导航和页面路由-UI开发 (ArkTS声明式开发范式)-ArkUI(方舟UI框架)-应用框架 - 华为HarmonyOS开发者
但是官方已经明确标注了不推荐了。转而推荐的是 Navigation 和 NavDestination 的结合:
组件导航 (Navigation)(推荐)-设置组件导航和页面路由-UI开发 (ArkTS声明式开发范式)-ArkUI(方舟UI框架)-应用框架 - 华为HarmonyOS开发者
页面创建方式:新旧对比 (Navigation vs Router) 🔄
这两者有什么区别?
官方原话:
组件导航(Navigation)和页面路由(@ohos.router)均支持应用内的页面跳转,但组件导航支持在组件内部进行跳转,使用更灵活。组件导航具备更强的一次开发多端部署能力,可以进行更加灵活的页面栈操作,同时支持更丰富的动效和生命周期。因此,推荐使用组件导航(Navigation)来实现页面跳转以及组件内的跳转,以获得更佳的使用体验。
在我看来,经过我的尝试,APP 首先还是使用的页面路由,我的证据是项目工程中 src > main > resources > profile 下依然会有一个文件
main_pages.json
里面声明了第一个页面的所在的位置。但是官方不推荐,那么有可能有无法避免的问题导致官方不得不换一种方式解决。理由可能是他们说的灵活性、多端适配、动效、生命周期等。从我们要实现帮助企业完成一个应用开发的角度,我们是不希望去撞这个南墙的,我们知难而退,就采用 Navgation 方案就好了。
"Hello World" 初体验与代码解读 👋
当我们创建了一个项目的时候大家应该已经有了一个预设的 Hello,world 页面了,大概的代码如下:
ts
@Entry
@Component
struct Page {
@State message: string = 'Hello World';
build() {
RelativeContainer() {
Text(this.message)
.id('PageHelloWorld')
.fontSize($r('app.float.page_text_font_size'))
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
.onClick(() => {
this.message = 'Welcome';
})
}
.height('100%')
.width('100%')
}
}
页面的样子大概是这样:

这个时候 SwiftUI 开发者拍案而起。😂
哈哈哈,没错,太熟悉了是吧。让我们看一个 swiftUI 的页面示例。
swift
//
// Hello.swift
// test
//
// Created by YOYOJ on 2025/5/25.
//
import SwiftUI
struct Hello: View {
var body: some View {
NavigationStack {
ExtractedView()
.navigationTitle("欢迎")
.navigationBarTitleDisplayMode(.inline)
}
}
}
#Preview {
Hello()
}
struct ExtractedView: View {
var body: some View {
VStack(spacing: 20) {
Text("hello") // 这里调用了国际化的单词
// 添加新路由示例
Button("前往详情") {
// path.append("Detail")
}
}
}
}
这段SwiftUI的页面结果是这样的:

所以我说鸿蒙是集大成者应该不为过吧。
哈哈哈其实也不尽然,因为我发现 Arkts 的 struct 它不是 Swift 的 struct 。这点我们下面会讲。
其实这里的 build 函数可以单纯的看作是一个 render 函数。然后里面写的是其他的 struct。
写到这儿我在想------是不是 React Native 对 JSX 或者 TSX 有版权?然后 Flutter 是设计了一种范式而没有版权,所以大家都用这种声明式范式? 🤔
我只是做个假象和猜测,没有验证这一说法。
回到鸿蒙我们继续。
鸿蒙这个 Hello,word 的代码给了我们很多信息。
- 状态属性需要使用
@State
来声明。 - 使用
$r
来使用资源内容,通过 app.[float|string|media|rowfile|boolean]来选择对应的资源。 - 点击事件使用 onClick 方法传递回调函数实现。
这里的 alignRules 大家可以留意一下,虽然大部分情况下是用不到的。但通过这个写法,我觉得在一些特定的对齐处理变化里面是有用的,预估是在切换对齐容器对象上,我没有做验证。(习惯一下,这个作者就是喜欢揣测,大家可以讨论)。
好了,了解了这些基本信息后,我们就要想要怎么进行布局和开发了。
🎨 布局与组件基础
依然是官方文档:
开发布局-UI开发 (ArkTS声明式开发范式)-ArkUI(方舟UI框架)-应用框架 - 华为HarmonyOS开发者


我们大部分需要用到的东西就这些。对于一些特别的用法,官方文档也有了非常多的文档说明,并给出了示例用法。
🧱 struct
的奥秘
这一部分主要是作者的一些对 struct 的理解和猜测。
盲猜,肯定有很多教培或者视频告诉你,把它当类来看。他们这么说其实也没错,但是它并不完全是类,它在鸿蒙这里定义的确实是一种结构
。细心的小伙伴会发现它也有static
、private
,不知道有没有人试过写 construct
构造函数🫣。
另外,熟悉 swiftUI 的小伙伴会不会尝试 extension
一下呢?就想这样:
swift
extension Hello {
func add() -> Int {
1 + 1
}
}
相信做过这些尝试的人会立即发现,它不是一个标准的 class、或者是一个标准的 struct。class 创建对象是需要 new 关键字的,而鸿蒙的 struct 却仿佛是当函数用一样,但是函数后面又立即能接一段表达式(大括号)的代码结构让很多人都难以理解,只能懵懵懂懂的写过去。
是的,就想个磨人的小妖精。怎么这么奇怪。我想有一部分考虑是简化类似安卓 compose 的写法。另外也是学习了 Flutter 和 SwiftUI 的一些 idea。所以才造就现在的 四不像(不像安卓,不像 swiftUI,不像 Flutter,更不像 ReactNative)
。但我还是推荐大家把它当 Swift 的结构体来理解,虽然是残缺的,但是大概意思是合得来的。它不是简单的类。因为如果是类,那么要做到所有使用这个结构写的都是组件的识别工作,那么一定会有一个公共的父类,实际上是没有的。所以当我们需要 UIContext,或者需要写明一个组件的类型的时候会发现巨难,因为无法获取到当前结构体的公共类型是什么。原因是他本身就是类型,没有父类。鸿蒙的编译器会直接把struct 当做组件来解析,build就是渲染函数。所以生命周期函数也不是重载。这一切的封装我们完全找不到源头。
🧭 页面导航精讲
原"页面路由"部分将在这里详细展开,重点介绍 Navigation 和 NavDestination 的使用。
这里我主要还是采用了一些官方文档中的示例。官方文档也非常详细。我这里主要提出一些大家常用的,避免在看官方文档的时候有选择困难症。另外也是帮助一些小伙伴更快的把路由用起来。
官方文档:组件导航 (Navigation)(推荐)-设置组件导航和页面路由-UI开发 (ArkTS声明式开发范式)-ArkUI(方舟UI框架)-应用框架 - 华为HarmonyOS开发者
这个新的路由方式我当时非常的费解。因为这个非常想 swiftUI 的路由方式。但是不同的是它还是要写路由的,方式我目前知道的有两种:一种是通过代码进行定义,另一种则是通过 router_map 文件来进行定义。让我们快速看看这两种方式。
大家可以稍作了解即可,如果需要有什么快速实现的办法,我个人比较推荐直接去看货拉拉开源的 TheRouter。TheRouter|OpenHarmony三方库中心仓
官方已经使用 Apache License 2.0 开源了,大家放心食用。
下面先上一个不使用 router_map 的方式:
ts
// 引入必要的模块
import { Navigation, NavPathStack, NavPathInfo, LaunchMode } from '@ohos.arkui.components';
// 定义A页面
@Builder
function PageABuilder(name: string, param: Object) {
return PageA();
}
@Component
struct PageA {
pageInfos: NavPathStack = new NavPathStack();
build() {
return NavDestination() {
Column() {
Text('这是A页面')
.fontSize(20)
.margin(20);
Button('跳转到B页面', { stateEffect: true, type: ButtonType.Capsule })
.width('80%')
.height(40)
.margin(20)
.onClick(() => {
this.pageInfos.pushPathByName('pageB', null);
});
Button('跳转到C页面', { stateEffect: true, type: ButtonType.Capsule })
.width('80%')
.height(40)
.margin(20)
.onClick(() => {
this.pageInfos.pushPathByName('pageC', null);
});
}
};
}
}
// 定义B页面
@Builder
function PageBBuilder(name: string, param: Object) {
return PageB();
}
@Component
struct PageB {
pageInfos: NavPathStack = new NavPathStack();
build() {
return NavDestination() {
Column() {
Text('这是B页面')
.fontSize(20)
.margin(20);
Button('跳转到D页面', { stateEffect: true, type: ButtonType.Capsule })
.width('80%')
.height(40)
.margin(20)
.onClick(() => {
this.pageInfos.pushPathByName('pageD', null);
});
}
};
}
}
// 定义C页面
@Builder
function PageCBuilder(name: string, param: Object) {
return PageC();
}
@Component
struct PageC {
pageInfos: NavPathStack = new NavPathStack();
build() {
return NavDestination() {
Column() {
Text('这是C页面')
.fontSize(20)
.margin(20);
Button('跳转到D页面', { stateEffect: true, type: ButtonType.Capsule })
.width('80%')
.height(40)
.margin(20)
.onClick(() => {
this.pageInfos.pushPathByName('pageD', null);
});
}
};
}
}
// 定义D页面
@Builder
function PageDBuilder(name: string, param: Object) {
return PageD();
}
@Component
struct PageD {
build() {
return NavDestination() {
Column() {
Text('这是D页面')
.fontSize(20)
.margin(20);
}
};
}
}
// 主页面
@Entry
@Component
struct MainPage {
pageInfos: NavPathStack = new NavPathStack();
build() {
return Navigation(this.pageInfos) {
PageABuilder('pageA', null);
}
.title('导航示例')
.width('100%')
.height('100%');
}
}
在上述代码中:
- 首先创建了
NavPathStack
实例来管理页面路由栈。 - 分别定义了 A、B、C、D 四个页面组件,每个页面都包含用于跳转的按钮,通过
pushPathByName
方法实现页面间的跳转。例如,A 页面中的按钮点击事件会调用pushPathByName
方法并传入目标页面的name
(如pageB
或pageC
),实现从 A 页面跳转到 B 或 C 页面;B 和 C 页面的按钮点击则会跳转到 D 页面。 - 在主页面
MainPage
中,将NavPathStack
实例传入Navigation
组件,并在Navigation
组件内部放置 A 页面的构建函数PageABuilder
,以此作为初始页面展示。这样就完成了基于Navigation
组件的页面组织,实现了 A、B、C、D 四个页面间的特定导航关系。
在鸿蒙开发中,通常采用 MVC 或 MVVM 架构思想,将视图(UI)与业务逻辑分离,以提高代码的可维护性和复用性。所以你也可以把这些代码拆开,形成这样的结构:
plaintext
pages/
├── index.ets # 主入口文件
├── pageA.ets # A页面
├── pageB.ets # B页面
├── pageC.ets # C页面
├── pageD.ets # D页面
└── viewModels/ # 业务逻辑层
├── pageAViewModel.ets
├── pageBViewModel.ets
├── pageCViewModel.ets
└── pageDViewModel.ets
使用系统路由表(router_map.json)来组织页面
这是我主要使用的方式。从API version 12开始,Navigation支持使用系统路由表的方式进行动态路由。各业务模块(HSP/HAR)中需要独立配置route_map.json文件,在触发路由跳转时,应用只需要通过NavPathStack提供的路由方法,传入需要路由的页面配置名称,此时系统会自动完成路由模块的动态加载、页面组件构建,并完成路由跳转,从而实现了开发层面的模块解耦。系统路由表支持模拟器但不支持预览器。
假设我们已经写好了页面:
ts
// 跳转页面入口函数
// 注意这里一定要添加这个一个 Builder 函数,提供给 router_map 的 buildFunction 属性。
// 同时需要注意,这里不能使用箭头函数,必须使用 function 进行函数声明。不然无法使用。
@Builder
export function PageOneBuilder() {
PageOne();
}
@Entry // 原则上此注解不应该加,但是为了能在预览器上使用手机视图查看页面情况需要加
@Preview // 加上此注解可以使用预览器进行预览
@Component // 写 struct 必须要加上此声明
export struct PageOne {
pathStack: NavPathStack = new NavPathStack();
build() { // build 函数必须要有
NavDestination() {
Text("Hello, world!")
}
.title('PageOne')
.onReady((context: NavDestinationContext) => {
this.pathStack = context.pathStack; // 此函数的作用是从上下文获取路由管理器来覆盖现有的路由管理器 pathStack。必须要确保使用同一个 pathStack(相同堆内存地址)。
})
}
}
并且我们准备从前置的 Index 页面跳转到这里来:
ts
// Index.ets
@Entry
@Component
struct Index {
pageStack : NavPathStack = new NavPathSÏtack();
build() {
Navigation(this.pageStack){
Text("这是 APP 首页")
}.onAppear(() => {
this.pageStack.pushPathByName("PageOne", null, false);
})
.hideNavBar(true)
}
}
那么,我们需要做如下配置:
- 在跳转目标模块的配置文件module.json5添加路由表配置:
json
{
"module" : {
"routerMap": "$profile:route_map"
}
}
- 添加完路由配置文件地址后,需要在工程resources/base/profile中创建route_map.json文件。添加如下配置信息:
json
{
"routerMap": [
{
"name": "PageOne",
"pageSourceFile": "src/main/ets/pages/PageOne.ets",
"buildFunction": "PageOneBuilder",
"data": {
"description" : "this is PageOne"
}
}
]
}
此时肯定有小伙伴开始觉得,这不扯吗?为什么不直接使用 pages_map.json 组织完所有的页面呢?或者直接同意都使用 pages_map.json 来配置。这样配置看起来可比 pages_map.json 麻烦多了。
我建议先别杠,先做。我们能想到华为开发框架的那些人不可能说没考虑到这个问题。其次,使用 pages_map.json 就是使用的原来的 router 导航的方案。我们前面说过,可能有什么难以避免的问题,我们是为了快速实现一个 APP,所以我也没进行深究。
🧩 创建第一个自定义组件
这里就直接上代码了,大家直接参考就完事儿了。
如果需要传入自定义组件,并设置插槽,可以使用属性装饰器 BuilderParam,但是这个参数一定要预先使用一个 Builder 函数进行初始化。不能使用联合类型给 undefined 或者是 null。
下面的示例会带上这个。
ts
@Component
struct Child {
@Builder
customBuilder() {
}
@BuilderParam customBuilderParam: () => void = this.customBuilder;
build() {
Column() {
this.customBuilderParam()
}
}
}
@Entry
@Component
struct Parent {
@Builder
componentBuilder() {
Text(`Parent builder `)
}
build() {
Column() {
Child({ customBuilderParam: this.componentBuilder }) // 这里向 Child 传值了。其他属性传值也是这样的。可以理解为标签属性使用了一个对象进行传递。
}
}
}
🖼️ 在页面中展示第一张图片
把图片放置在 media 目录下:

使用的时候只需要使用$r
进行引用即可,就想这样:
ts
@Component
struct MyComponent {
build() {
Column() {
Image($r('app.media.background'))
}
}
}

正常情况下,当输入app.
的时候编辑器就已经会提示出来能用的资源了。图片我们选择媒体资源即可。
需要注意:media 目录下必须是平铺的,不能有目录结构。简而言之就是不能创建目录,目录索引不到,且会编译报错。
其他图片资源的玩法
1、本地图片
图片资源在鸿蒙中不仅可以放在 resource 目录下作为 Resource 资源进行使用,将本地图片放入ets文件夹下的任意位置也是可以正常使用的。
ts
Image('images/view.jpg') // 这里假设在同级的 images 目录下存放了 view.jpg
.width(200)
但是这种做法我个人认为有一些弊端:
-
资源文件散落在工程目录下的任意位置,不好管理
-
官方提示:加载本地图片过程中,如果对图片进行修改或者替换,可能会引起应用崩溃。因此需要覆盖图片文件时,应该先删除该文件再重新创建一个同名文件。说明存在一些加载编译问题。可能会导致开发体验不是很好。
从我目前开发鸿蒙的经验来说,最妥善的做法就是放到 resource 目录下统一管理。
2、网络资源
引入网络图片需申请权限ohos.permission.INTERNET,具体申请方式请参考声明权限。此时,Image组件的src参数为网络图片的链接。
网络图片必须支持RFC 9113标准,否则会导致加载失败。如果下载的网络图片大于10MB或一次下载的网络图片数量较多,建议使用HTTP工具提前预下载,提高图片加载性能,方便应用侧管理数据。
ts
Image('https://www.example.com/example.JPG') // 实际使用时请替换为真实地址
3、放在rawfile文件夹下。
用法类似于media。个人不推荐,理由是从工程项目整洁度角度考虑。
ts
Image($rawfile('example1.png'))
4、从媒体库或 base64
ts
// 媒体库
Image('file://media/Photos/5')
.width(200)
// base64
Image('data:image/[png|jpeg|bmp|webp|heif];base64,[base64 data]') // 其中[base64 data]为Base64字符串数据。
个人调试的时候发现,只要确定 base64 的内容是图片,可以免去 MIME 类型。使用格式类似: data:image;base64,[base64 data]
不过个人不推荐,写清楚是更为妥善的做法。避免出现不必要的 bug。
当然,图片还有其他玩法,大家可以去看看官方文档:显示图片 (Image)-添加组件-UI开发 (ArkTS声明式开发范式)-ArkUI(方舟UI框架)-应用框架 - 华为HarmonyOS开发者
🌐 实现第一条国际化(i18n)文本
在 resource > base 目录上鼠标右击,选择 Resource Directory,会出现这样的弹窗:

这里我们选择 Locale。并点击 >
将选项移动到右侧。在 Language 中选择需要的国际化选项,这里我们以 zh: Chinese
为例,然后选择 CN:China
。别急着点击 OK,我们还需要选择资源类型。
会不会有小伙伴像我一样才发现这些国际化简写之中的奥妙,同时惊叹于世界之大。


请确保使用的是 Element。其他类型的资源,在特殊情况下是可能需要的哦。完事儿了我们点击 ok。如果有小伙伴此时的项目目录类型选择的是 Ohos,可能就会产生疑问:有什么变化?
你没错,我也没错,编辑器也没错。请点击目录类型切换为 Project,这个时候可能就看到了。


这个时候大家肯定也有和我当时一样的疑问------难道编辑器有问题。No!如果我们此时留意到了目录结构,当我们切换回 Ohos 的时候就可以打开 AppScope,国际化配置目录会对你说:"在!我一直都在!"

原谅我这里绕了一个圈子讲,我想让大家更多的注意到目录结构的变化,这样当下次出现问题的时候,避免寻找文件要找半天。因为这种项目有 model 这一说,可能存在相同命名的配置文件,但是配置各自模块的。AppScope 和 entry 就是两个模块。
额外讲个小技巧,大家可以点击提示出来的编辑器按钮,在一个表格视图中编辑国际化内容,可以更直观的看到国际化结构


实测,这里的搜索不好用。要搜索的话还是到原来的 string.json 中使用搜索工具搜索吧。或者双击 shift 都会比这个好用。
🐞 应用调试技巧
预览
給 struct 添加上@Entry
的注解后就可以看到手机的预览图了

如果你再多加一个@Preview
那么你就可以在另一种视图中看到了。这种我比较推荐设计组件的时候单独使用。

预览的交互日志在 log 中查看:

Preview Log 是加载预览的日志输出
模拟器运行和调试

选择设备,这里我没有安装模拟设备所以是空的,需要什么类型的设备直接从 Device Manager 中下载即可。运行就是直接在模拟器中预览,点击小虫子(debug)按钮是支持进行断点调试的。直接在编辑器中你想要中断的行点击出现红点即可进行调试。(这个相信经常使用 Idea 或者是 Android studio 的人特别熟)
当然,如果你有华为的真机,也可以直接链接上去使用真机进行调试。
模拟器或者真机运行日志也是通过 log 选项卡进行查看的。但是模拟器或者真机运行的时候,这里会打印出手机所有的日志信息,如果要看到开发的 APP 的信息,可以使用 Filter 进行筛选。推荐使用 APPId 进行筛选后再使用搜索定位到你特定的打印内容会比较好看一点。不然花海会非常多杂乱的日志信息。

🔮 总结与展望
鸿蒙开发总归来说是不难的,它集成了多个方面的开发思想,包括前端、iOS、Android、Flutter 等。有时候我甚至和同事开玩笑说,鸿蒙这是挖坑勾引开发者去学习和做鸿蒙开发。不过也确实,学习鸿蒙开发真的不需要花费多少时间。至于之前网上爆火的课,我现在觉得,我这一篇简短的小文章,都可以抵上 1/3 了吧,结合官方文档,直接有了 2/3。剩下的 1/3 就是作为开发者的读者,请你要动手写出一个 APP 了,写完了,你就是尊贵的鸿蒙开发工程师了。加油💪。
好啦,我终于写完了这篇鸿蒙开发入门文档。虽然内容也算是非常多了,但是还是省略了一部分非常简单的内容的。比如编辑器的安装。但我相信这是难不倒各位大佬的。主要还是在帮助大家更快上手。个人稍微话痨,谅解一下。
这篇文章是在我完成第一个鸿蒙开发任务后进行总结的。虽然不是非常精辟,但也是花了两三天的工作之余的空闲时间来修改和完善。希望大家多多支持。同时也欢迎大家一起来讨论。