鸿蒙(HarmonyOS NEXT / Stage 模型)完整开发手册(前端工程师专属)

定位:ArkTS + ArkUI 声明式范式(官方主推,复杂交互、生产首选)
面向:有 React / Vue + TS 基础的前端工程师
内容:基本功 + 语法 + 核心机制 + 横向对比 + 注意事项 + 编程规范 + 核心功能点 + 实战模板
前置说明:HarmonyOS NEXT 统一使用 Stage 应用模型,FA 模型已废弃。本手册全部基于 Stage 模型、ArkTS、ArkUI 声明式开发范式,不介绍老旧类 Web(HML/CSS/JS)范式。


目录

  1. 鸿蒙整体介绍 & 前端视角对比(Vue/React)
  2. 开发环境、工程结构、Stage 模型基础
  3. ArkTS 基础语法(对比 TS/JS,重点差异、限制)
  4. ArkUI 声明式 UI 基础语法、组件、布局
  5. 状态管理(重中之重,V1+V2 两套体系)
  6. 渲染控制、条件渲染、循环渲染(ForEach / LazyForEach)
  7. 事件体系、手势、复杂交互
  8. 路由导航 Navigation(推荐)vs router(旧)
  9. 动画、转场、渐变、绘图(Canvas)
  10. 网络、本地存储、文件、权限、媒体
  11. 自定义组件、@Builder、@BuilderParam、封装组件
  12. 编程规范(官方规范)
  13. 高频注意事项、踩坑清单(前端最容易踩的坑)
  14. 多设备适配、响应式、栅格、媒体查询
  15. 分布式能力(鸿蒙独有,跨设备)
  16. 性能优化、内存、渲染优化
  17. 调试、打包、签名、上架
  18. 实战模板:复杂交互页面(列表+下拉刷新+表单+弹窗)
  19. 学习路线
  20. 官方权威文档地址

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)Vue3React
UI 写法代码内 DSL,build(){},无单独模板SFC 模板 + script setupJSX
状态基础@State / @StateV2,装饰器ref / reactiveuseState / useReducer
组件通信@Prop、@Link、@ObjectLink、@Consume/@Provideprops、emit、provide/injectprops、context
列表渲染ForEach、LazyForEach(长列表必用)v-formap
条件渲染if / elsev-if&& / 三元
样式链式调用 .width().padding(),支持 style 复用style、class、scssstyle、className、css-in-js
路由Navigation(推荐)vue-routerreact-router
更新粒度组件标脏,状态驱动组件更新Proxy 依赖收集Fiber 协调、虚拟 DOM diff
运行时AOT 预编译,方舟字节码,无 JS 引擎解释V8V8
动态特性大量禁用:any、动态增删对象属性、对象展开、解构支持 JS 动态特性支持 JS 动态特性
跨端鸿蒙全设备:手机、平板、车机、手表、智慧屏web 优先,uni-app 等封装web 优先,RN

前端思维最大转变:放弃 DOM 操作思维,不要去"获取组件实例修改属性",所有 UI 变更必须改状态;没有 document、没有 querySelector、没有 ref 拿 DOM 节点改样式。

1.3 两种开发范式(再次强调)

  1. ArkTS 声明式(主推):性能高、能力全、适合复杂交互、长期维护,本手册全部基于此
  2. 类 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 };

❌ 严格禁止(前端高频翻车):

  1. 禁止 any / unknown,编译直接报错;不知道类型就定义 interface、类型断言 as User
  2. 禁止动态给对象新增 / 删除属性,对象结构编译期固定
// ❌ 错误
let obj = { name: 'a' };
obj.age = 18;
  1. 对象展开运算符 {...obj} 不支持;数组展开 [...arr] 支持
  2. 对象解构赋值禁止,数组解构也有限制;只能手动取值
// ❌ 不支持 const { name } = user;
// ✅ 正确:const name = user.name;
  1. 类是标称类型(Nominal):两个 class 字段完全一样,不能互相赋值;interface 是结构化鸭子类型,和 TS 一致
  2. 不支持映射类型 type A<T> = { [k in keyof T]: ... }
  3. 不支持 call / apply / bind 动态修改 this
  4. 所有类属性必须初始化,不能留空不赋值(和 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 / GridColGrid 栅格响应式栅格,多设备适配首选
List + ListItem虚拟列表长列表,LazyForEach 必须放 List 内
Grid + GridItemCSS Grid宫格
Swiperswiper 轮播轮播图
Tabs + TabContentTabs 标签页标签

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 全局状态方案选型

  1. 简单全局:@AppStorage(V1)
  2. 复杂全局、多页面共享、嵌套对象:V2 + 单例 class(推荐,替代 pinia)
  3. 跨 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 本地存储

  1. @StorageLink:轻量 KV 持久化(类似 localStorage),最大 4096 字节,适合简单配置
  2. @ohos.data.preferences:偏好 KV 存储,适合配置项
  3. @ohos.data.relationalStore:关系型数据库(SQLite),大量结构化数据
  4. @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. 自定义组件、组件封装(做组件库基础)

  1. 组件必须 @Component struct,不能 class
  2. 组件拆分原则:单一职责,和前端组件拆分思路一致
  3. @BuilderParam 插槽、@Param 入参、@Link 双向绑定
  4. 组件内生命周期:aboutToAppear(组件创建前,等价 onMounted)、aboutToDisappear(销毁前,onUnmounted)

没有 onUpdate,不要在 aboutToAppear 写无限循环、异步不清理,容易内存泄漏。

@Component
struct MyButton {
  @Prop title: string = '';
  @BuilderParam icon: () => void = () => {};

  build() {
    Button(this.title);
  }
}

12. ArkTS 官方编程规范(强制,DevEco Lint 校验)

  1. 命名
    • 类、struct、枚举:大驼峰 UpperCamelCase
    • 变量、函数、参数:小驼峰 lowerCamelCase
    • 常量:全大写,下划线分隔 MAX_COUNT
    • 布尔变量:带 is / has 前缀 isShow、hasData,禁止 isNotShow
  2. 缩进:空格,禁止 tab;行宽 ≤ 120 字符
  3. 字符串:优先单引号
  4. 所有变量、函数参数显式标注类型,不依赖隐式推断偷懒
  5. 访问修饰符:尽量加 public / private
  6. 禁止一行多个变量声明
  7. if / for / while 必须写大括号
  8. 接口、模型统一放 model 目录,不要散落在页面
  9. UI 组件只做 UI 渲染,业务逻辑抽离到 model / utils(和前端分离思想一致)
  10. 禁止在 build() 里面写大量业务逻辑、网络请求、复杂计算!build 是渲染函数,只放 UI 描述

重要红线:build() 里面不要写异步请求、不要修改状态,会无限循环刷新。


13. 高频注意事项 & 前端专属踩坑清单(重中之重)

思维类坑(90% 前端新人踩)

  1. ❌ 想拿组件实例、修改组件属性(web ref 思维);✅ 全部走状态驱动
  2. ❌ 命令式操作 UI;✅ 先改状态,框架自动刷新
  3. ❌ 把 ArkTS 当成 TS 随便写;✅ 它是受限强类型语言,很多 JS 特性直接砍掉
  4. ❌ build() 里面写请求、循环、复杂计算;✅ build 只负责 UI 描述,请求放 aboutToAppear 或者点击回调

语法坑

  1. 禁止 any、禁止动态新增对象属性、禁止对象解构、禁止对象展开
  2. struct 组件不能 new,直接在 UI 里写 MyComponent() 形式
  3. 数组修改:V1 中直接 push 不会刷新!V1 数组属于引用类型,必须重新赋值 this.arr = [...this.arr](数组展开支持,对象展开不支持);V2 @Trace 数组可以直接 push
  4. ForEach / LazyForEach 必须 key,key 必须稳定唯一,不要用 index 当 key(和 React 一样)
  5. 事件不冒泡,没有 stopPropagation

状态坑

  1. 普通变量改了不刷新,必须加对应装饰器
  2. @AppStorage V1 对象内部属性修改不刷新,必须整体替换
  3. V2 @ObservedV2 只对 class 生效,interface 不行
  4. 不要滥用 @Provide / @Consume,层级太深难以调试,优先显式传参

渲染性能坑

  1. 长列表不用 LazyForEach,直接 ForEach,滑动卡顿、内存爆炸
  2. 大组件没有合理拆分,一个页面几千行 build,标脏范围过大,整页刷新
  3. 动画频繁修改大量状态,掉帧;优先 animateTo、属性动画
  4. Image 组件不设置 objectFit,大图不裁剪,内存飙升

路由 & 生命周期坑

  1. NavDestination 页面退出,组件 aboutToDisappear,状态销毁;不要把持久数据放页面 @State
  2. 不要大量 UIAbility,多 UIAbility 会分成多个任务卡片
  3. 异步定时器、事件监听,在 aboutToDisappear 必须清除,否则内存泄漏

权限 & 打包坑

  1. 敏感权限必须动态申请,静态声明只是注册
  2. 网络图片、http,必须权限 + 网络安全配置
  3. 真机调试、打包签名,签名文件和 bundleName 必须匹配

14. 多设备响应式适配(鸿蒙核心能力,前端 media query)

  1. 单位优先 vp,字体 fp,不要 px
  2. GridRow / GridCol 栅格系统:自动在手机 / 平板 / 车机自动排布(类似 bootstrap 栅格)
  3. @ohos.mediaquery 媒体查询:监听屏幕宽度、横竖屏变化
  4. 设备类型判断:手机、平板、车机、手表,做差异化布局

前端习惯写固定 px,鸿蒙必须从一开始就做响应式,一个包跑多设备。


15. 鸿蒙独有:分布式能力(前端没有的)

分布式是鸿蒙区别于 web、其他跨端框架最大特色:

  • 分布式数据对象:跨设备实时同步数据(手机和平板数据联动)
  • 分布式任务调度:拉起其他设备的应用
  • 分布式文件:跨设备访问文件

适用场景:多端协同、跨设备投屏、接力;需要额外权限、设备组网,开发复杂度高,属于进阶能力。


16. 性能优化总纲(复杂交互页面必看)

  1. 组件拆分:最小化标脏范围,状态尽量下沉到子组件
  2. 列表:长列表强制 LazyForEach,设置合理缓存数量
  3. Image:提前设置宽高、裁剪、缓存,使用 Image 的 syncLoad 按需加载
  4. 动画:优先 animateTo,避免高频状态变更
  5. 计算逻辑:不要放 build,抽成 V2 计算属性或者缓存结果
  6. 及时销毁:定时器、订阅、监听在 aboutToDisappear 清理
  7. 避免超大 @State 对象,状态粒度尽量细
  8. 预览器 / 模拟器性能和真机不一样,性能测试必须真机

17. 调试、打包、签名

  1. 调试:console.info 日志、预览器实时刷新、性能面板(内存、帧率、渲染)
  2. 性能分析工具:Profiler,看 UI 渲染耗时、内存泄漏
  3. 打包:hap 包,需要签名证书;调试证书、发布证书分开
  4. 上架华为应用市场:隐私声明、权限说明、多设备适配、兼容性测试

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. 学习路线(看完手册之后)

  1. 先跑通上面模板,熟悉 V2 状态、LazyForEach、动画、弹窗
  2. 封装基础组件库(按钮、输入框、卡片、弹窗、下拉)
  3. 封装 http 请求、全局 toast、loading、权限工具
  4. 做中型项目:商城列表、表单、图片上传、详情页
  5. 进阶:自定义绘制 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
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐