HarmonyOS 从完全不懂到 TODO LIST 开发
前段时间我有幸被掘金邀请参加了鸿蒙的培训。作为一个 Web 前端开发者,在参加培训前对鸿蒙一无所知。然而,经过培训后我意外地发现鸿蒙 Next 原生开发如此容易上手,对于前端开发者学习成本非常低,需要学习的新东西非常少,特写一篇速通文章分享我的所学。
本文将从一个前端开发者的角度出发,速通鸿蒙 Next 开发的方方面面,并最终开发一个 Todo List 小实例。
简介
首先,鸿蒙使用 ArkTS
作为原生开发语言。如果你熟悉 TypeScript
编程语言,那基本上可以无缝过渡,因为 ArkTS 并不是一门全新的语言,而是在 TypeScript 基础上进行扩展的。这意味着我们可以跳过学习新语言的阶段,只需学习鸿蒙的 UI 框架 ArkUI
。
类似于 React,ArkUI 框架采用声明式的开发范式来描述 UI,并且内置了完善的状态管理机制,无需像 React 那样面对各种混乱的第三方状态库。
鸿蒙内置组件的布局设计基于 CSS
的概念,包括 margin
、padding
、flex
、grid
、栅格系统和媒体查询等,这些都是前端开发者所熟悉的。
鸿蒙 Next 提供了完整的开发、调试、测试和发布一站式 IDE。如果你之前使用过 IntelliJ IDEA,那么对你来说将是无缝衔接的,因为鸿蒙的 DevEco 是基于 IntelliJ IDEA Community
进行深度定制的。但如果你跟我一样是 Neovim
或者 VSCode
的死忠粉的话,也没有关系 DevEco
其实是很好上手的。
IDE 介绍
工欲善其事,必先利其器,我们先看看鸿蒙的 IDE 怎么用
DevEco-Studio 安装
目前提供3个版本可供下载
- Windows(64-bit)
- Mac(X86)
- Mac(ARM)
注意目前版本需要 Node 18.x
环境,前端开发者建议安装 nvm,事先切换好 Node 版本。
安装好 nvm 后
这样你在安装 DevEco 的时候就可以选择 Local 的 Node 环境了,如果你本地没有 Node,也可以选择全新安装
接下来如果一切顺利,在 Diagnose
界面就会看到满屏的对号,表示安装成功了。
我相信你能摸索着创建一个 Hello Wrold 项目
接下来会看到树形列表中默认创建了大量的文件,跟我刚开始一样,不知如何下手,经过研究发现很多文件是有两份的,一个是模块级的,一个是整个应用级的。
为了清楚起见,我画了一张图,图中左侧列出的文件,都是应用和模块的两个版本的。
整个 entry
目录叫做一个 Module
,该目录会编译为一个 .hap
为后缀的文件,HAP 包。
等应用最终上架时,会打包成 .app
为扩展名的文件,上传到华为商店。
Module
不只有 entry
类型的,还有其他类型的,简单起见,我还是总结一张图:
初看是有点头大,其实作为入门,只需要关注的 entry
模块,其他 Module
类型可等到深入开发时再去文档了解。
entry
目录下有一个 src/main/ets/pages/index.ets
文件,这是用户看到的第一个页面,我们先把该文件打开看个大概,后边编程语言的部分会详细介绍对应语法。
第一行的 @Entry
装饰器表明这是应用的入口,中间 build()
方法返回的就是整个声明式UI的页面结构。
翻译过来就是一个满高的 Row 组件之中放了一个满宽的 Column 组件,里边放了一个 50 大小文本组件。
右上角选中 previewer
,点击 run
按钮即可运行,并预览效果。
输出效果
这就是整个开发流程了,刚才的代码怎么看着这么眼熟,是 TypeScript ?
编程语言
鸿蒙的主要开发语言是 ArkTS(.ets 文件)。看着眼熟是因为它是 TypeScript 的超集,基本上就是 TS 代码,最大的区别或者说特点,就是在编译时对静态类型的检查和分析做了增强,并对一些动态特性做了少量的限制。这使得程序在运行时类型都是已知的,减少了运行时 bug 并提升了程序性能。
比如,强制类型不允许使用 any
或 unknown
类型。也不能使用 obj as any
之类的语法动态给对象添加属性和方法,更不能在运行时使用 delete
删除属性或方法。在某些需要 any 类型的情况下,建议使用 Record\<string, Object>
类型。
编译器默认打开了 TypeScript 的一些严格模式,比如 strictPropertyInitialization
,要求强制给定初始值。strictNullChecks
强制进行空值安全检查等。
总之,你能想到的运行时的动态类型特性都会被限制,都尽量不要使用。更多详细的语法规则可以参考官方文档中关于《从 TypeScript 到 ArkTS 的适配规则》的文章,内容非常详细。实际上,在开发过程中,DevEco Studio 会提供很好的错误报告信息,因此你可以先不必了解这些语法规则,等到遇到问题时再去查询。
UI框架
ArkUI 框架是基于 ArkTS 的UI 框架,使用声明式的开发范式,数据驱动 UI 更新,并且提供了页面级路由导航等。
在页面布局方面提供了多种媒体查询,比如
- 设备类型
- 窗口宽高监听
- 折叠屏状态
- 横竖屏查询
统一了单位,比如
vp
虚拟像素fp
字体像素,用户端的设置会乘以系数1fp = 1vp * scale
并且提供了多种栅格系统,窗口栅格会根据容器宽度,自动匹配栅格数量
栅格 | size | 宽度 | 设备 |
---|---|---|---|
4格 | small | 360~600 | 手机竖屏 |
8格 | medium | 600~840 | 手机横屏,pad 竖屏,折叠屏 |
12格 | large | 840~1440 | pad 横屏,2in1 |
12格 | x-large | 1440~ | 全屏 |
需要注意的是,目前稳定主推的应用模型叫做Stage模型,如果你在学习的过程中看到FA模型,那就是就是旧版教程,可以不用看了。
光说不练是假把式,下边我们在代码层面了解一下如何声明 UI
声明式UI 描述
声明式 UI 的描述方式如下
Column 是容器组件,所以后边带{}
,里边包含子组件,非容器组件则无需{}
给组件配置属性通常用链式调用的方法
为了更加清晰,通常会写成这种格式
添加事件处理
装饰器
ArkUI 中大量的使用的装饰器,包括我们之前看到的 @entry
表示入口,再看一个最简单的自定义组件:
ArkUI 中用 @Component
装饰的 struct
结构代表自定义组件。
目前流行数据驱动 UI 的编程范式,所谓 UI = f(State)
, 少不了状态,
ArkUI 中用 @State
装饰器来声明状态,Parent 可以直接覆盖 Child State
和 React 中的 State 类似,状态的变化可以引起 UI 更新,但注意这个状态不是 immutable 的,UI 是否可以观察到状态的变化要看数据类型,具体要参考详细的文档。
下边是典型的事件处理中修改状态,引起 UI 刷新的例子:
@State
只是组件内部的状态。如果想在状态更改时引发 Child 组件的更新,就要了解 @Props
装饰器了
@Props
用于接收 Parent 组件的更新,给接收端属性前加上 @Props
装饰器后,就很类似 React 中的 props 传递了,不同的是 @Props
属性自身改变也会引起 UI 更新,类似 React 的 props 和 state 的结合体,看以下例子:
除了单向数据流,ArkUI 还提供了双向数据绑定的装饰器 @Link
,
跨层级共享数据的 @Provide
和 @Consume
装饰器有些类似 react 中的 useContext
。
画了个图总结一下,可以根据你的需要用的时候再去查文档。
一个实例
今天做一个学习新语言最常见的简易 ToDo List,请看下边代码,包含了详细注释
自定义列表项放入另一个目录 src/main/ets/ui/Item.ets
在模拟器中的显示效果
结语
通过上边的学习,可以看出相比于安卓的苹果两大系统,鸿蒙的开发相对于前端开发者来说友好得多。
在如此低迷的经济环境下,衷心希望鸿蒙系统在市场上可以取得大成功,给我们前端开发仔开辟一条新的赛道。
最后,非常感谢掘金和华为此次的邀请,期待下次有机会再聚。