鸿蒙(HarmonyOS NEXT / Stage 模型)完整开发手册(前端工程师专属)
鸿蒙(HarmonyOS NEXT / Stage 模型)完整开发手册(前端工程师专属)
定位:ArkTS + ArkUI 声明式范式(官方主推,复杂交互、生产首选)
面向:有 React / Vue + TS 基础的前端工程师
内容:基本功 + 语法 + 核心机制 + 横向对比 + 注意事项 + 编程规范 + 核心功能点 + 实战模板
前置说明:HarmonyOS NEXT 统一使用 Stage 应用模型,FA 模型已废弃。本手册全部基于 Stage 模型、ArkTS、ArkUI 声明式开发范式,不介绍老旧类 Web(HML/CSS/JS)范式。
目录
- 鸿蒙整体介绍 & 前端视角对比(Vue/React)
- 开发环境、工程结构、Stage 模型基础
- ArkTS 基础语法(对比 TS/JS,重点差异、限制)
- ArkUI 声明式 UI 基础语法、组件、布局
- 状态管理(重中之重,V1+V2 两套体系)
- 渲染控制、条件渲染、循环渲染(ForEach / LazyForEach)
- 事件体系、手势、复杂交互
- 路由导航 Navigation(推荐)vs router(旧)
- 动画、转场、渐变、绘图(Canvas)
- 网络、本地存储、文件、权限、媒体
- 自定义组件、@Builder、@BuilderParam、封装组件
- 编程规范(官方规范)
- 高频注意事项、踩坑清单(前端最容易踩的坑)
- 多设备适配、响应式、栅格、媒体查询
- 分布式能力(鸿蒙独有,跨设备)
- 性能优化、内存、渲染优化
- 调试、打包、签名、上架
- 实战模板:复杂交互页面(列表+下拉刷新+表单+弹窗)
- 学习路线
- 官方权威文档地址
1. 鸿蒙整体介绍 & 前端视角对比
1.1 基础概念
- HarmonyOS NEXT:纯原生鸿蒙,无安卓兼容层,新应用全部推荐
- ArkTS:基于 TS 扩展的强类型语言,不是 JS/TS,有独立编译约束(AOT 编译),用于写业务逻辑 + UI 描述
- ArkUI:方舟 UI 框架,声明式 UI,DSL 内嵌在 ArkTS 代码里,没有 JSX,没有模板文件,UI 直接写在
build()函数内 - Stage 模型:应用模型,核心单元包括:
UIAbility(页面实例,类似一个独立窗口 / 任务)ExtensionAbility(卡片、服务、输入法等)- 最佳实践:一个 App = 1 个 UIAbility + 多个页面(NavDestination),不要多个 UIAbility,否则会分成多个最近任务卡片
- 核心思想:状态驱动视图,声明式描述 UI,不操作 DOM(ArkUI 没有 DOM 树)
1.2 横向对比(前端最关心)
| 维度 | ArkUI(ArkTS) | Vue3 | React |
|---|---|---|---|
| UI 写法 | 代码内 DSL,build(){},无单独模板 | SFC 模板 + script setup | JSX |
| 状态基础 | @State / @StateV2,装饰器 | ref / reactive | useState / useReducer |
| 组件通信 | @Prop、@Link、@ObjectLink、@Consume/@Provide | props、emit、provide/inject | props、context |
| 列表渲染 | ForEach、LazyForEach(长列表必用) | v-for | map |
| 条件渲染 | if / else | v-if | && / 三元 |
| 样式 | 链式调用 .width().padding(),支持 style 复用 | style、class、scss | style、className、css-in-js |
| 路由 | Navigation(推荐) | vue-router | react-router |
| 更新粒度 | 组件标脏,状态驱动组件更新 | Proxy 依赖收集 | Fiber 协调、虚拟 DOM diff |
| 运行时 | AOT 预编译,方舟字节码,无 JS 引擎解释 | V8 | V8 |
| 动态特性 | 大量禁用:any、动态增删对象属性、对象展开、解构 | 支持 JS 动态特性 | 支持 JS 动态特性 |
| 跨端 | 鸿蒙全设备:手机、平板、车机、手表、智慧屏 | web 优先,uni-app 等封装 | web 优先,RN |
前端思维最大转变:放弃 DOM 操作思维,不要去"获取组件实例修改属性",所有 UI 变更必须改状态;没有
document、没有querySelector、没有 ref 拿 DOM 节点改样式。
1.3 两种开发范式(再次强调)
- ArkTS 声明式(主推):性能高、能力全、适合复杂交互、长期维护,本手册全部基于此
- 类 Web 范式(HML + CSS + JS):类似小程序,性能弱、能力受限,新项目禁止使用
2. 开发环境、工程结构、Stage 模型
2.1 工具
DevEco Studio(官方 IDE,基于 IDEA),配套模拟器、真机调试、预览器- 预览器:实时预览,开发效率最高(类似 vite 预览)
- 模拟器:需要 CPU 虚拟化,Windows 开启 BIOS 虚拟化;Mac M 系列直接支持
- 真机:需要鸿蒙开发者账号、签名、USB 调试
2.2 标准 Stage 工程目录(重点)
entry/src/main/
├── ets/
│ ├── entryability/ # UIAbility 入口(应用启动入口)
│ │ └── EntryAbility.ets
│ ├── pages/ # 页面(NavDestination 页面)
│ │ ├── Index.ets
│ │ └── Detail.ets
│ ├── components/ # 自定义组件(业务组件)
│ ├── model/ # 数据模型、interface、枚举
│ ├── utils/ # 工具函数、请求封装
│ ├── router/ # 路由配置
│ └── app.ets # 全局入口
├── resources/ # 资源:图片、字符串、颜色、尺寸、多语言
└── module.json5 # 模块配置:权限、UIAbility、页面入口、meta
注意:
pages不是路由,只是存放页面文件;路由由Navigation容器管理,很多前端新手误以为 pages 就是路由表。
2.3 UIAbility 是什么
UIAbility = 应用窗口 / 任务实例,生命周期:
onCreate → onWindowStageCreate(在这里初始化 Navigation、加载首页)→ onForeground(前台)→ onBackground(后台)→ onDestroy
不要在 UIAbility 写页面 UI,UIAbility 只负责窗口、生命周期、全局初始化。
3. ArkTS 基础语法(对比 TS,这是前端踩坑重灾区)
ArkTS = TS 子集 + 扩展 UI 装饰器 + 强约束;不是完整 TS,很多 JS/TS 特性被禁用。
3.1 基础类型(和 TS 大体一致,但约束更强)
基础类型:string / number / boolean / null / undefined
复合:interface、class、enum、array(T[])、泛型
✅ 允许:
interface User {
name: string;
age: number;
}
let u: User = { name: '张三', age: 20 };
❌ 严格禁止(前端高频翻车):
- 禁止
any/unknown,编译直接报错;不知道类型就定义 interface、类型断言as User - 禁止动态给对象新增 / 删除属性,对象结构编译期固定
// ❌ 错误
let obj = { name: 'a' };
obj.age = 18;
- 对象展开运算符
{...obj}不支持;数组展开[...arr]支持 - 对象解构赋值禁止,数组解构也有限制;只能手动取值
// ❌ 不支持 const { name } = user;
// ✅ 正确:const name = user.name;
- 类是标称类型(Nominal):两个 class 字段完全一样,不能互相赋值;interface 是结构化鸭子类型,和 TS 一致
- 不支持映射类型
type A<T> = { [k in keyof T]: ... } - 不支持
call/apply/bind动态修改 this - 所有类属性必须初始化,不能留空不赋值(和 TS
strictPropertyInitialization一致)
3.2 函数、模块、导入导出
- 导出:
export,导入:import xxx from 'xxx',和 TS 一致 - 箭头函数支持;函数参数必须标注类型,不能隐式 any
- 模块路径:
@ohos是系统内置 API;相对路径导入组件
3.3 装饰器基础(ArkTS 独有,核心)
装饰器是 ArkUI 的灵魂,用来标记组件、状态、自定义构建函数。
@Component:标记自定义 UI 组件(必须!)@Entry:标记页面入口组件(放在 UIAbility 里渲染的根组件)@Builder:声明 UI 构建函数(可复用 UI 片段,类似 Vue 的 template 片段)@BuilderParam:接收 UI 片段参数(组件插槽,等价 Vue slot、React children)
最小 HelloWorld 模板:
@Entry
@Component
struct Index {
@State msg: string = 'Hello ArkTS';
build() {
Column() {
Text(this.msg);
Button('点击')
.onClick(() => {
this.msg = '更新了';
});
}
}
}
struct:ArkTS 用struct定义 UI 组件,不是class!struct 是轻量组件结构,不要用 class 写 UI 组件。
4. ArkUI 声明式 UI、基础组件、布局
4.1 UI 语法规则
build() 函数内写 UI,链式调用属性、事件;缩进表达嵌套关系。
Column() {
Text('A');
Row() {
Button('B');
}
}
.width('100%')
.padding(16)
.backgroundColor('#fff');
- 没有闭合标签;容器组件大括号内是子组件
- 样式是链式方法调用,没有 CSS 文件(也可以用
@Styles、@Extend抽样式) - 单位:默认
vp(虚拟像素,适配多设备,类似前端 rem);fp用于字体(跟随系统字体大小)1vp:设备无关像素,推荐;不要直接写px
4.2 布局容器(前端对照)
| 容器 | 等价前端 | 说明 |
|---|---|---|
Row() | flex-direction: row | 横向弹性布局 |
Column() | flex-direction: column | 纵向弹性布局(最常用) |
Stack() | position: relative + absolute | 层叠,子元素堆叠 |
Flex() | flex | 完整 flex,换行 wrap |
RelativeContainer | 相对定位 | 相对定位 |
GridRow / GridCol | Grid 栅格 | 响应式栅格,多设备适配首选 |
List + ListItem | 虚拟列表 | 长列表,LazyForEach 必须放 List 内 |
Grid + GridItem | CSS Grid | 宫格 |
Swiper | swiper 轮播 | 轮播图 |
Tabs + TabContent | Tabs 标签页 | 标签 |
4.3 基础系统组件
Text、Button、Image、TextInput、TextArea、Checkbox、Radio、Slider、Progress、Search、Divider
Image:支持本地资源、网络图片;网络图片需要申请网络权限。
4.4 样式复用方案(前端 css 替代)
1)@Styles:普通样式函数,只能放通用样式
@Styles function card() {
.width('100%')
.padding(16)
.borderRadius(12);
}
2)@Extend:扩展内置组件,给组件追加样式 + 属性(类似给组件加 class)
@Extend(Text) function title() {
.fontSize(20)
.fontWeight(FontWeight.Bold);
}
3)全局样式:resources 里的 color、float 资源,$r('app.color.xxx')
不支持 scss/less;没有样式隔离,自定义组件样式默认不隔离。
5. 状态管理(核心!复杂交互的根基,V1 / V2 两套)
一句话:只有被装饰器标记的变量,修改之后才会触发 UI 刷新;普通变量改了界面不动。
V1:代理观察;V2:原生对象可观察,深度监听、计算属性、变更前值,新项目优先 V2。
5.1 V1 状态装饰器(存量项目大量使用)
| 装饰器 | 作用 | Vue / React 类比 |
|---|---|---|
@State | 组件内私有状态 | ref / useState |
@Prop | 父传给子,单向只读 | props(只读) |
@Link | 父子双向绑定 | v-model |
@ObjectLink | 引用类型对象双向绑定 | 深层 reactive |
@Provide / @Consume | 跨多层组件透传 | provide / inject |
@StorageLink | 持久化到本地(类似 localStorage) | localStorage + 响应式 |
@AppStorage | 全局应用状态(单例) | pinia / global context |
⚠️ V1 重点坑:
@AppStorage如果是对象,直接修改对象内部属性不会刷新,必须整体重新赋值
// ❌ 不刷新
this.user.name = 'xxx';
// ✅ 刷新(但 ArkTS 不支持对象展开,只能新建对象)
this.user = { name: 'xxx', age: this.user.age };
5.2 V2 状态(推荐新项目,强大很多)
@StateV2、@ObservedV2、@Trace
@ObservedV2:标记 class,整个类可观察@Trace:标记类里面的字段,字段变更自动深度通知 UI
@ObservedV2
class UserModel {
@Trace name: string = '';
@Trace age: number = 0;
}
@Entry
@Component
struct Page {
user: UserModel = new UserModel();
build() {
Column() {
Text(this.user.name);
Button('改名字').onClick(() => {
// ✅ 直接修改属性,自动刷新,不需要整体赋值
this.user.name = '李四';
});
}
}
}
✅ V2 优势:深度监听、支持计算属性、可以拿到变更前的值、适合复杂表单、嵌套对象、大状态模型。
复杂交互、表单、数据中台类页面,直接上 V2。
5.3 全局状态方案选型
- 简单全局:
@AppStorage(V1) - 复杂全局、多页面共享、嵌套对象:V2 + 单例 class(推荐,替代 pinia)
- 跨 UIAbility:优先分布式数据,不要直接共享内存
5.4 对比前端响应式
- Vue3
reactive:自动代理、深度监听;ArkTS V2 是显式@ObservedV2+@Trace - React:状态不可变,必须 set;ArkTS V1 要求引用类型整体替换,V2 可变直接修改属性
6. 渲染控制:条件渲染、循环渲染(复杂列表、表单必备)
6.1 条件渲染
直接用 if / else,写在 build 内,不需要指令。
if (this.show) {
Text('显示');
} else {
Text('隐藏');
}
不支持三元直接放 UI(可以放文本),大分支必须
if / else。
6.2 循环渲染(重点,前端 v-for / map 对应)
1)ForEach:一次性渲染全部,适合短列表;数据量大会卡
ForEach(
this.list,
(item: ItemModel) => {
ListItem() {
Text(item.name);
}
},
(item: ItemModel) => item.id.toString() // key!必须唯一,和 React key 一样
);
2)LazyForEach:长列表、大数据列表必用!虚拟滚动,按需渲染,只在 List / Grid 容器内生效
LazyForEach需要实现IDataSource,比ForEach繁琐,但是性能差距巨大,做商品列表、聊天列表必须它。
高频坑:忘记 key,列表增删、排序时 UI 错乱;
LazyForEach不能脱离List直接使用。
6.3 @Builder 复用 UI 片段(插槽 @BuilderParam)
@Builder
function title(text: string) {
Text(text).fontSize(20);
}
// 组件插槽
@Component
struct Card {
@BuilderParam content: () => void = () => {};
build() {
Column() {
this.content();
}
}
}
// 使用
Card() {
Text('插槽内容');
}
等价 Vue slot、React children。
7. 事件、手势、复杂交互
7.1 基础事件
.onClick、.onTouch、.onLongPress、.onChange(输入框)
TextInput({ text: this.value })
.onChange((val: string) => {
this.value = val;
});
没有事件冒泡机制!和 web 完全不一样,没有
event.stopPropagation,嵌套组件点击互不冒泡,需要自己手动控制。
7.2 手势系统(复杂交互核心:拖拽、缩放、滑动、长按)
内置手势:TapGesture、LongPressGesture、PanGesture(拖拽)、PinchGesture(缩放)、RotateGesture
手势可以组合(同时识别、互斥识别):
Image($r('app.media.pic'))
.gesture(
PanGesture()
.onActionUpdate((e: GestureEvent) => {
// 拖拽偏移 e.offsetX / e.offsetY
})
);
做画板、拖拽排序、图片缩放、卡片滑动,全部靠这套手势 API,是复杂交互的重点。
7.3 焦点事件、键盘事件
.onKeyEvent,适合表单、快捷键、TV / 车机交互。
8. 路由导航 Navigation(官方推荐,替代旧 router)
❌ 旧
@ohos.router不推荐新项目,属于栈式简单路由,缺少转场、多栈、嵌套导航;Navigation容器是标准方案。
Navigation 是导航容器,内部放 NavDestination(页面),支持:
- 路由栈、push、pop、popTo、replace
- 页面转场动画、自定义页面动画
- 嵌套导航(Tab 内子页面)
- 路由参数传递(简单参数、对象参数)
@Entry
@Component
struct Index {
stack: NavPathStack = new NavPathStack();
build() {
Navigation() {
NavDestination() {
// 首页内容
}.title('首页');
}
.navDestination(this.pageMap)
.mode(NavigationMode.Stack);
}
@Builder
pageMap(name: string, param: Object) {
if (name === 'Detail') {
DetailPage({ param: param as DetailParam });
}
}
}
路由栈 NavPathStack 管理页面栈:
this.stack.pushPath({ name: 'Detail', param: { id: 1 } });
前端类比:react-router + 页面栈;区别:鸿蒙路由是栈模型,没有前端 hash / history 路由,是原生窗口栈。
路由参数注意
- 基础类型直接传;复杂对象推荐 V2 可观察对象或者序列化,不要传超大对象
- 页面销毁时
NavDestination会自动销毁状态,离开页面状态丢失,和页面组件生命周期一致
9. 动画、转场、绘图
9.1 属性动画(最简单,类似 Vue transition)
.animation({ duration: 300 }),修改状态自动触发动画:
@State x: number = 0;
Button('移动')
.onClick(() => { this.x = 200; })
.translate({ x: this.x })
.animation({ duration: 300, curve: Curve.EaseInOut });
9.2 显式动画 animateTo(手动控制动画,复杂交互首选)
animateTo({ duration: 500 }, () => {
this.x = 200;
});
适合弹簧动画、序列动画、拖拽松手回弹、弹窗弹出动画。
9.3 页面转场、组件共享元素转场
Navigation 支持页面自定义转场;共享元素用于详情页图片放大动画。
9.4 Canvas 绘图(自定义绘制、图表、画板)
Canvas 组件 + CanvasRenderingContext2D,API 和 web Canvas 高度相似!前端上手极快。
图表:可以用 Canvas 自己封装,或者使用鸿蒙三方图表库。
9.5 渐变、阴影、滤镜
linearGradient、shadow、blur,链式属性调用,和 css 能力接近。
10. 网络、存储、权限、文件、媒体
10.1 网络请求 @ohos.net.http
- 没有 axios!需要自己封装请求拦截器、响应拦截器(前端常规工作)
- 网络权限:
ohos.permission.INTERNET,module.json5声明 - 支持 http / https;异步回调 / async await
注意:鸿蒙网络不是浏览器环境,没有 fetch、XMLHttpRequest。
10.2 本地存储
@StorageLink:轻量 KV 持久化(类似 localStorage),最大 4096 字节,适合简单配置@ohos.data.preferences:偏好 KV 存储,适合配置项@ohos.data.relationalStore:关系型数据库(SQLite),大量结构化数据@ohos.file.fs:文件系统,读写本地文件、图片缓存
对比前端:localStorage ≈ Preferences;IndexedDB ≈ relationalStore。
10.3 权限体系(移动端重点,前端最容易忽略)
权限分为:普通权限、敏感权限(位置、相机、相册、麦克风)
- 普通权限:
module.json5静态声明,安装自动授予 - 敏感权限:动态申请,运行时弹窗向用户申请,需要
@ohos.promptAction/abilityAccessCtrl申请
原则:最小权限,不要一次性申请全部权限,用到再申请。
10.4 媒体:拍照、相册、音频视频
@ohos.camera、@ohos.photoAccessHelper、@ohos.multimedia.audio、@ohos.multimedia.video
相册现在新版用
photoAccessHelper,废弃旧的 media 库。
11. 自定义组件、组件封装(做组件库基础)
- 组件必须
@Component struct,不能 class - 组件拆分原则:单一职责,和前端组件拆分思路一致
@BuilderParam插槽、@Param入参、@Link双向绑定- 组件内生命周期:
aboutToAppear(组件创建前,等价 onMounted)、aboutToDisappear(销毁前,onUnmounted)
没有
onUpdate,不要在aboutToAppear写无限循环、异步不清理,容易内存泄漏。
@Component
struct MyButton {
@Prop title: string = '';
@BuilderParam icon: () => void = () => {};
build() {
Button(this.title);
}
}
12. ArkTS 官方编程规范(强制,DevEco Lint 校验)
- 命名
- 类、struct、枚举:大驼峰
UpperCamelCase - 变量、函数、参数:小驼峰
lowerCamelCase - 常量:全大写,下划线分隔
MAX_COUNT - 布尔变量:带
is/has前缀isShow、hasData,禁止isNotShow
- 类、struct、枚举:大驼峰
- 缩进:空格,禁止 tab;行宽 ≤ 120 字符
- 字符串:优先单引号
- 所有变量、函数参数显式标注类型,不依赖隐式推断偷懒
- 访问修饰符:尽量加
public/private - 禁止一行多个变量声明
if/for/while必须写大括号- 接口、模型统一放
model目录,不要散落在页面 - UI 组件只做 UI 渲染,业务逻辑抽离到
model/utils(和前端分离思想一致) - 禁止在
build()里面写大量业务逻辑、网络请求、复杂计算!build 是渲染函数,只放 UI 描述
重要红线:
build()里面不要写异步请求、不要修改状态,会无限循环刷新。
13. 高频注意事项 & 前端专属踩坑清单(重中之重)
思维类坑(90% 前端新人踩)
- ❌ 想拿组件实例、修改组件属性(web ref 思维);✅ 全部走状态驱动
- ❌ 命令式操作 UI;✅ 先改状态,框架自动刷新
- ❌ 把 ArkTS 当成 TS 随便写;✅ 它是受限强类型语言,很多 JS 特性直接砍掉
- ❌
build()里面写请求、循环、复杂计算;✅ build 只负责 UI 描述,请求放aboutToAppear或者点击回调
语法坑
- 禁止
any、禁止动态新增对象属性、禁止对象解构、禁止对象展开 struct组件不能 new,直接在 UI 里写MyComponent()形式- 数组修改:V1 中直接
push不会刷新!V1 数组属于引用类型,必须重新赋值this.arr = [...this.arr](数组展开支持,对象展开不支持);V2@Trace数组可以直接 push ForEach/LazyForEach必须 key,key 必须稳定唯一,不要用 index 当 key(和 React 一样)- 事件不冒泡,没有 stopPropagation
状态坑
- 普通变量改了不刷新,必须加对应装饰器
@AppStorageV1 对象内部属性修改不刷新,必须整体替换- V2
@ObservedV2只对 class 生效,interface 不行 - 不要滥用
@Provide/@Consume,层级太深难以调试,优先显式传参
渲染性能坑
- 长列表不用
LazyForEach,直接ForEach,滑动卡顿、内存爆炸 - 大组件没有合理拆分,一个页面几千行 build,标脏范围过大,整页刷新
- 动画频繁修改大量状态,掉帧;优先
animateTo、属性动画 Image组件不设置objectFit,大图不裁剪,内存飙升
路由 & 生命周期坑
NavDestination页面退出,组件aboutToDisappear,状态销毁;不要把持久数据放页面@State- 不要大量 UIAbility,多 UIAbility 会分成多个任务卡片
- 异步定时器、事件监听,在
aboutToDisappear必须清除,否则内存泄漏
权限 & 打包坑
- 敏感权限必须动态申请,静态声明只是注册
- 网络图片、http,必须权限 + 网络安全配置
- 真机调试、打包签名,签名文件和
bundleName必须匹配
14. 多设备响应式适配(鸿蒙核心能力,前端 media query)
- 单位优先
vp,字体fp,不要px GridRow/GridCol栅格系统:自动在手机 / 平板 / 车机自动排布(类似 bootstrap 栅格)@ohos.mediaquery媒体查询:监听屏幕宽度、横竖屏变化- 设备类型判断:手机、平板、车机、手表,做差异化布局
前端习惯写固定 px,鸿蒙必须从一开始就做响应式,一个包跑多设备。
15. 鸿蒙独有:分布式能力(前端没有的)
分布式是鸿蒙区别于 web、其他跨端框架最大特色:
- 分布式数据对象:跨设备实时同步数据(手机和平板数据联动)
- 分布式任务调度:拉起其他设备的应用
- 分布式文件:跨设备访问文件
适用场景:多端协同、跨设备投屏、接力;需要额外权限、设备组网,开发复杂度高,属于进阶能力。
16. 性能优化总纲(复杂交互页面必看)
- 组件拆分:最小化标脏范围,状态尽量下沉到子组件
- 列表:长列表强制
LazyForEach,设置合理缓存数量 - Image:提前设置宽高、裁剪、缓存,使用
Image的syncLoad按需加载 - 动画:优先
animateTo,避免高频状态变更 - 计算逻辑:不要放 build,抽成 V2 计算属性或者缓存结果
- 及时销毁:定时器、订阅、监听在
aboutToDisappear清理 - 避免超大
@State对象,状态粒度尽量细 - 预览器 / 模拟器性能和真机不一样,性能测试必须真机
17. 调试、打包、签名
- 调试:
console.info日志、预览器实时刷新、性能面板(内存、帧率、渲染) - 性能分析工具:Profiler,看 UI 渲染耗时、内存泄漏
- 打包:hap 包,需要签名证书;调试证书、发布证书分开
- 上架华为应用市场:隐私声明、权限说明、多设备适配、兼容性测试
18. 实战模板:复杂交互页面(列表 + 下拉刷新 + 表单 + 弹窗)
这个模板可以直接新建文件跑,包含:V2 状态、
LazyForEach、下拉刷新、弹窗、表单输入、按钮提交、动画。
import { LazyDataSource } from '../model/LazyDataSource';
@ObservedV2
class PageModel {
@Trace list: Array<ItemModel> = [];
@Trace loading: boolean = false;
@Trace dialogShow: boolean = false;
@Trace inputVal: string = '';
}
interface ItemModel {
id: number;
name: string;
}
@Entry
@Component
struct ComplexDemoPage {
model: PageModel = new PageModel();
dataSource: LazyDataSource = new LazyDataSource(this.model.list);
aboutToAppear(): void {
this.loadData();
}
async loadData(): Promise<void> {
this.model.loading = true;
// 模拟请求
setTimeout(() => {
this.model.list = [
{ id: 1, name: '项目A' },
{ id: 2, name: '项目B' }
];
this.model.loading = false;
}, 800);
}
@Builder
dialog() {
if (this.model.dialogShow) {
Column() {
TextInput({ text: this.model.inputVal })
.onChange((v: string) => { this.model.inputVal = v; });
Button('确认')
.onClick(() => { this.model.dialogShow = false; });
}
.width('80%')
.padding(20)
.backgroundColor('#fff')
.borderRadius(12);
}
}
build() {
Column() {
Button('打开弹窗')
.onClick(() => {
animateTo({ duration: 200 }, () => {
this.model.dialogShow = true;
});
});
List() {
LazyForEach(this.dataSource, (item: ItemModel) => {
ListItem() {
Text(item.name)
.width('100%')
.padding(16);
}
}, (item: ItemModel) => item.id.toString());
}
.refresh({
refreshing: this.model.loading,
onRefresh: () => { this.loadData(); }
});
}
.overlay(this.dialog());
}
}
配套
LazyDataSource需要自己实现IDataSource,是长列表标准写法。
19. 学习路线(看完手册之后)
- 先跑通上面模板,熟悉 V2 状态、
LazyForEach、动画、弹窗 - 封装基础组件库(按钮、输入框、卡片、弹窗、下拉)
- 封装 http 请求、全局 toast、loading、权限工具
- 做中型项目:商城列表、表单、图片上传、详情页
- 进阶:自定义绘制 Canvas、手势复杂交互、分布式、原生能力
20. 官方权威文档地址(随时查阅)
- ArkUI:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkui-overview-V13
- ArkTS 语言:https://device.harmonyos.com/cn/docs/apiref/harmonyos-guides/introduction-to-arkts
- Stage 模型:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/uiability-overview-V5
更多推荐





所有评论(0)