# OpenHarmonyDoc **Repository Path**: lingjie666/open_harmony_doc ## Basic Information - **Project Name**: OpenHarmonyDoc - **Description**: https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/application-dev-guide.md演示工程 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-04-11 - **Last Updated**: 2026-01-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 说明 1、来源:本工程是 [OpenHarmony 应用开发文档](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/application-dev-guide.md) 的演示工程。 2、目的:**旨在把文档内容代码化,方便开发时查询。** 3、版本: v4.1 Release API 11 Release---截止2024.04.11 # 应用开发导读 # 入门 ## 快速入门 ### 开发准备 Stage模型: ![stage-concepts.png](README_PIC%2Fstage-concepts.png) ### 构建第一个ArkTS应用(Stage模型) ## 开发基础知识 ### 应用程序包基础知识 #### 应用程序包概述 HAP(分entry和feature)、HAR、HSP所有文档链接罗列如下: 1、[Module类型](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/application-package-overview.md#module%E7%B1%BB%E5%9E%8B) 2、[编译态包结构-->选择合适的包类型](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/application-package-structure-stage.md#%E7%BC%96%E8%AF%91%E6%80%81%E5%8C%85%E7%BB%93%E6%9E%84) 3、[HAP](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/hap-package.md) 4、[HAR](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/har-package.md) 5、[HSP](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/in-app-hsp.md) 6、[动态import](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-dynamic-import.md) 7、[工程管理](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/key-features/multi-device-app-dev/ide-using.md) 8、受2启发:当多包(HAP/HSP)同时引用同一个共享包时,采用HSP替代HAR,可以避免HAR造成的多包间代码和资源的重复拷贝,从而减小应用包大小。---我的理解:当HAR被应用内共享时,外包一层HSP,以避免包体积膨胀和状态无法共享问题。 9、受2启发:HAR和HSP没有XxxAbility,意味着它们不能独立运行,只能依赖HAP。 10、受3启发:因为HAP不支持导出接口和ArkUI组件,给其他模块使用,所以HAP和HAP之间没有依赖关系,但是可以通过[UIAbility组件间交互(设备内)](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/application-models/uiability-intra-device-interaction.md)进行通信。 11、[如果HAR包含HSP发布,第三方无法引用!](https://developer.huawei.com/consumer/cn/forum/topic/0201148559224036438?fid=0109140870620153026) #### 应用程序包结构 ##### Stage模型应用程序包结构 AppScope:应用的全局配置信息。由DevEco Studio自动生成,不可更改。 resources :用于存放应用需要用到的资源文件。编译后会合入到模块(比如“entry”)下面资源目录中,如果两个目录下的存在重名文件,编译打包后只会保留AppScope目录下的资源文件。---stage模型多工程情况下,共有的资源文件放到此目录。 entry:应用的主模块,包含应用的入口界面、入口图标和主功能特性,编译后生成entry类型(module.json5中的“type”字段)的HAP包。每一个应用分发到 >>同一类型<< 的设备上的应用程序包,只能包含唯一一个entry类型的HAP。目录名称可以自定义。 src > main > ets:用于存放ArkTS源码文件(.ets文件)。编译后会生成.abc文件。 src > main > ets > entryability:应用/服务的入口。 src > main > ets > pages:应用/服务包含的页面。 src > main > resources:用于存放应用/服务所用到的资源文件,如图形、多媒体、字符串、布局文件等。关于资源文件,详见资源文件的分类①。 base:默认存在的目录。二级子目录element用于存放字符串、颜色、布尔值等基础元素,media、profile存放媒体、动画、布局等资源文件。 en_US:默认存在的目录,设备语言环境是美式英文时,优先匹配此目录下资源。二级子目录element用于存放字符串、颜色、布尔值等基础元素,media、profile存放媒体、动画、布局等资源文件。 zh_CN:默认存在的目录,设备语言环境是简体中文时,优先匹配此目录下资源。二级子目录element用于存放字符串、颜色、布尔值等基础元素,media、profile存放媒体、动画、布局等资源文件。 en_GB-vertical-car-mdpi:自定义限定词目录示例,由开发者创建 rawfile:其他类型文件目录,支持创建多层子目录,子目录名称可以自定义,文件夹内可以自由放置各类资源文件。文件以文件形式保存,不会被集成到resources.index文件中。文件名可自定义。 resfile:其他类型文件目录,支持创建多层子目录,子目录名称可以自定义,文件夹内可以自由放置各类资源文件。文件以文件形式保存,不会被集成到resources.index文件中。文件名可自定义。资源会被解压到应用沙箱路径,通过Context属性resourceDir获取到resfile资源目录后,可通过文件路径访问。 feature1:应用的动态特性模块,编译后生成feature类型(module.json5中的“type”字段)的HAP包。一个应用中可以包含0、1或多个feature类型的HAP。 library_static1:静态共享库。编译后会生成一个以.har为后缀的文件,即静态共享包HAR(Harmony Archive)。 library_shared1:动态共享库。编译后会生成一个以.hsp为后缀的文件,即动态共享包HSP(Harmony Shared Package)。实际上,Shared Library编译后除了会生成一个.hsp文件,还会生成一个.har文件。这个.har文件中包含了HSP对外导出的接口,应用中的其他模块需要通过.har文件来引用HSP的功能。为了表述方便,我们通常认为Shared Library编译后生成HSP。 oh_modules:用于存放三方库依赖信息。 ①:[资源文件的分类](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/resource-categories-and-access.md) ##### FA模型应用程序包结构 #### 应用程序包开发与使用 ##### HAP ##### HAR ##### HSP ##### 动态import(API 11) #### 应用程序包安装卸载与更新 ### 应用配置文件(Stage模型) #### 应用配置文件概述(Stage模型) #### app.json5配置文件 #### module.json5配置文件 ### 应用配置文件(FA模型) ## 资源分类与访问 ## 学习ArkTS语言 ### 初识ArkTS语言 ### ArkTS语言介绍 ### 从TypeScript到ArkTS的适配指导 ### UI范式 #### 基本语法 ##### 基本语法概述 ##### 声明式UI描述 ##### 自定义组件 ###### 创建自定义组件 | 装饰器 | 使用位置 | 作用 | URL | |:----------:|:---------:|:-------------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| | @Entry | Page页入口组件 | 一个页面最多一个此装饰的组件 | [自定义组件的基本结构](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-create-custom-components.md#%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BB%84%E4%BB%B6%E7%9A%84%E5%9F%BA%E6%9C%AC%E7%BB%93%E6%9E%84) | | @Component | 每个组件 | 仅装饰struct。使struct具备组件化的能力 | [自定义组件的基本结构](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-create-custom-components.md#%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BB%84%E4%BB%B6%E7%9A%84%E5%9F%BA%E6%9C%AC%E7%BB%93%E6%9E%84) | 注:组件专指自定义组件。 ###### 页面和自定义组件生命周期 - onDidBuild:组件build()函数执行完成之后回调该接口,开发者可以在这个阶段进行埋点数据上报等不影响实际UI的功能。`不建议在其中更改状态变量、使用animateTo等功能`。 - aboutToDisappear:在自定义组件析构销毁之前执行。`不允许在其中改变状态变量`。 ###### 自定义组件的自定义布局 ###### 自定义组件冻结功能 ##### @Builder装饰器:自定义构建函数 - [在@Builder修饰的函数内部,不允许改变参数值。](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-builder-V5#参数传递规则) - [只有传入一个参数,且参数需要直接传入对象字面量才会按引用传递该参数,其余传递方式均为按值传递。](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-builder-V5#参数传递规则) - [按引用传递参数时,传递的参数可为状态变量,且状态变量的改变会引起@Builder方法内的UI刷新。](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-builder-V5#按引用传递参数) - [引用传递的\$\$也可以换成其他名称,\$\$不是必须的参数形式。](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-builder-V5#多层builder方法嵌套使用) - 不支持从@Builder装饰器直接传给整个$$给自定义组件。 ##### wrapBuilder:封装全局@Builder(API 11) ##### @Styles装饰器:定义组件重用样式 ##### @Extend装饰器:定义扩展组件样式 ##### stateStyles:多态样式 ##### @AnimatableExtend装饰器:定义可动画属性 ##### @Require装饰器:校验构造传参(API 11) ##### @Reusable装饰器:组件复用 @Reusable装饰器使用限制: - [不建议嵌套使用](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-reusable-V5#限制条件) - [可复用自定义组件的缓存和复用只能发生在同一父组件下。比如A组件是可复用组件,其也是B组件的子组件,并进入了B组件的可复用节点缓存中,但是在C组件中创建A组件时,无法使用B组件缓存的A组件](https://developer.huawei.com/consumer/cn/doc/best-practices-V5/bpta-component-reuse-V5#section1048675564013) - [可复用自定义组件中嵌套自定义组件,如果想要对嵌套的子组件的内容进行更新,需要实现对应子组件的aboutToReuse生命周期回调。](https://developer.huawei.com/consumer/cn/doc/best-practices-V5/bpta-component-reuse-V5#section1048675564013) - [若自定义组件复用的前后使用了渲染控制语法显著的改变了自定义组件的组件树结构,那么将无法享受到组件复用带来的性能提升](https://developer.huawei.com/consumer/cn/doc/best-practices-V5/bpta-component-reuse-V5#section1048675564013) | 官方说明 | 官方反例 | |:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:-------------------------------------------------------------------------------------------------------------:| | [搭配LazyForEach使用时,只有直接写在LazyForEach内的组件,复用才能生效。例如LazyForEach里面直接写的是父组件A,其包含有@Reusable标识的子组件B,但此时子组件B不会实现组件复用。](https://developer.huawei.com/consumer/cn/doc/best-practices-V5/bpta-component-reuse-V5#section10249447201311) | [组合型](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-reusable-V5#多种条目类型使用场景) | | [由于ForEach渲染控制语法的全展开属性,不能触发组件复用](https://developer.huawei.com/consumer/cn/doc/best-practices-V5/bpta-component-reuse-V5#section1048675564013) | [Foreach使用场景](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-reusable-V5#foreach使用场景) | @Reusable装饰器使用场景: - 配合LazyForEach使用 - List使用场景 - [标准型](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-reusable-V5#列表滚动配合lazyforeach使用) - [有限变化型](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-reusable-V5#多种条目类型使用场景) - [组合型](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-reusable-V5#多种条目类型使用场景):将父组件改为builder函数,让子组件共享组件复用池。 - [Grid使用场景](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-reusable-V5#grid使用场景) - [WaterFlow使用场景](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-reusable-V5#waterflow使用场景) - Swiper使用场景 - [一般场景](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-reusable-V5#swiper使用场景) - [Swiper嵌套WaterFlow](https://developer.huawei.com/consumer/cn/doc/best-practices-V5/bpta-global-custom-component-reuse-V5):使用全局自定义组件复用。 - [ListItemGroup使用场景](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-reusable-V5#listitemgroup使用场景) - 配合if使用 - [单reuseId](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-reusable-V5#动态布局更新) - [多reuseId](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-reusable-V5#if使用场景) - [配合Foreach使用](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-reusable-V5#foreach使用场景) @Reusable装饰器最佳实践: - [只要是发生了相同自定义组件销毁和再创建的场景,都可以使用组件复用。](https://developer.huawei.com/consumer/cn/doc/best-practices-V5/bpta-component-reuse-V5#section5601835174020) - [在组件复用场景下,过深的自定义组件的嵌套会增加组件复用的使用难度,推荐优先使用@Builder替代自定义组件](https://developer.huawei.com/consumer/cn/doc/best-practices-V5/bpta-component-reuse-V5#section109991333141413) - [复用场景常用在高频的刷新场景,使用attributeUpdater精准控制组件属性的刷新](https://developer.huawei.com/consumer/cn/doc/best-practices-V5/bpta-component-reuse-V5#section4470171391314) - [如果复用组件内部使用了if/else来控制布局的结构,那么最好设置为多个reuseId](https://developer.huawei.com/consumer/cn/doc/best-practices-V5/bpta-component-reuse-V5#section4981115441415) - [使用状态变量替代函数/方法作为复用组件创建时的入参](https://developer.huawei.com/consumer/cn/doc/best-practices-V5/bpta-component-reuse-V5#section18721184816136) | 装饰器 | 使用位置 | 作用 | URL | |:-----------------:|:------------------------------------------:|:----------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------:| | @Builder | 封装UI描述的函数 | 使函数遵循build()函数语法规则,复用UI元素 | [@Builder装饰器:自定义构建函数](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-builder.md) | | @BuilderParam | `组件内`成员变量(变量类型必须是@Builder装饰的函数) | 父组件传递@Builder装饰的函数给子组件 | [@BuilderParam装饰器:引用@Builder函数](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-builderparam.md) | | @Require | `组件内`成员变量(必须是@Prop或@BuilderParam装饰的变量) | 限制@Prop和@BuilderParam装饰的变量必须在构造时传参 | [@Require装饰器:校验构造传参](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-require.md) | | @Styles | 封装通用属性和通用事件的函数 | 复用 | [@Styles装饰器:定义组件重用样式](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-style.md) | | @Extend | 封装属性、事件和自定义`全局`函数(比如@Styles装饰的全局函数)的`全局`函数 | 复用 | [@Extend装饰器:定义扩展组件样式](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-extend.md) | | @AnimatableExtend | 封装属性的`全局`函数 | 主要是让 不可动画属性 也能实现动画效果 | [@AnimatableExtend装饰器:定义可动画属性](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-animatable-extend.md) | | @Reusable | `自定义组件`声明上 | 使自定义组件可以复用 | [@Reusable装饰器:组件复用](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-reusable-V13) | | 函数 | 使用位置 | 作用 | URL | |:----------------------------------------------------------------------:|:----:|:----------------------------------:|:-------------------------------------------------------------------------------------------------------------------------:| | wrapBuilder(@Builder builder: (...args: Args) => void): WrappedBuilder | | 封装1~N个全局@Builder构建函数 | [wrapBuilder:封装全局@Builder](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-wrapBuilder.md) | | * stateStyles(value: StateStyles): T | 通用属性 | 设置不同状态下样式,类似Android中的selector(选择器) | [stateStyles:多态样式](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-statestyles.md) | 注: 1、组件:这里专指自定义组件。 2、属性:属性方法简称。 3、事件:事件方法简称。 4、样式:属性和事件。 5、UI描述:系统组件、属性和事件。 6、* :优先掌握。 #### 状态管理 ##### 状态管理概述 ![arkts-state-management-overview.png](README_PIC%2Farkts-state-management-overview.png) - 组件状态: @Component | 装饰器 | 使用位置 | 初始化 | 组件内同步 | 组件间同步 | 父初始化 | 初始化子 | URL | |:-----------:|:----------------------:|:--------:|:-----:|:-----------------------:|:------------------------------------------------------------------------------------------------------------------:|:-------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------:| | @State | `组件内`成员变量 | 本地 | Y | 取决于搭配的装饰器 | 无状态、@State、@Prop、@Link、@ObjectLink、@Provide、@Consume、@StorageProp、@StorageLink、@LocalStorageProp、@LocalStorageLink | 无状态、@State、@Prop、@Link、@Provide | [@State装饰器:组件内状态](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-state.md) | | @Prop | `组件内`成员变量 | 父/本地 | Y | 父装饰器 -> 子@Prop | 无状态、@State、@Prop、@Link、@ObjectLink、@Provide、@Consume、@StorageProp、@StorageLink、@LocalStorageProp、@LocalStorageLink | 无状态、@State、@Prop、@Link、@Provide | [@Prop装饰器:父子单向同步](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-prop.md) | | @Link | `组件内`成员变量 | 父 | Y | 父装饰器 <-> 子@Link | @State、@Prop、@Link、@ObjectLink、@Provide、@Consume、@StorageProp、@StorageLink、@LocalStorageProp、@LocalStorageLink | 无状态、@State、@Prop、@Link、@Provide | [@Link装饰器:父子双向同步](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-link.md) | | @ObjectLink | `组件内`被@Observed装饰的成员变量 | 父 | Y | 父装饰器 <-> 子@ObjectLink | @State、@Link、@ObjectLink、@Provide、@Consume | 无状态、@State、@Prop、@Link、@Provide | [@Link装饰器:父子双向同步](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-link.md) | | @Provide | `组件内`成员变量 | 父/本地 | Y | 父@Provide <-> 子@Consume | 无状态、@State、@Prop、@Link、@ObjectLink、@Provide、@Consume、@StorageProp、@StorageLink、@LocalStorageProp、@LocalStorageLink | @State、@Prop、@Link、@Provide | [@Provide装饰器和@Consume装饰器:与后代组件双向同步](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-provide-and-consume.md) | | @Consume | `组件内`成员变量 | @Provide | Y | 父@Provide <-> 子@Consume | @Provide | @State、@Link、@Prop、@Provide | [@Provide装饰器和@Consume装饰器:与后代组件双向同步](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-provide-and-consume.md) | @ComponentV2 | 装饰器 | 使用位置 | 初始化 | 组件内同步 | 组件间同步 | 父初始化 | 初始化子 | URL | |:---------:|:-------------------------------------------------------:|:------------:|:---------------------:|:-------------------------------------:|:---------:|:---------:|:--------------------------------------------------------------------------------------------------------------------------------------------:| | @Local | `组件内`成员变量 | 本地 | @Local <-> 组件内部 | N | N | Y | [@Local装饰器:组件内部状态](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-new-local-V13) | | @Param | `组件内`成员变量 | 父/本地 | @Param -> 组件内部 | 父装饰器 -> 子@Param | Y | Y | [@Param:组件外部输入](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-new-param-V13) | | @Once | `组件内`被@Param装饰的成员变量 | 父 | @Param @Once <-> 组件内部 | N | Y | Y | [@Once:初始化同步一次](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-new-once-V13) | | @Event | `组件内`被@Param装饰的成员变量 相关的 函数类型成员变量 | 父/本地 | | 父@Local -> 子@Param;父@Local <- 子@Event | Y | Y | [@Event装饰器:规范组件输出](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-new-event-V13) | | @Provider | `组件内`成员变量 | 本地 | Y | 父@Provider <-> 子@Consumer | | @Consumer | [@Provider装饰器和@Consumer装饰器:跨组件层级双向同步](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-new-provider-and-consumer-V13) | | @Consumer | `组件内`成员变量 | 本地/@Provider | Y | 父@Provider <-> 子@Consumer | @Provider | | [@Provider装饰器和@Consumer装饰器:跨组件层级双向同步](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-new-provider-and-consumer-V13) | | 需求 | 实现 | |:----------------------:|:---------------------------------------:| | 组件内部同步 | @Local | | 组件内部同步 & 父组件初始化子组件 | @Param @Once | | 组件内部不需要同步 & 父组件 -> 子组件 | @Param | | 父组件 <-> 子组件 | 父:@Local;子变量:@Require @Param;子方法:@Event | | 隔代同步 | 爷:@Provider;孙:@Consumer | - 应用状态: @Component | 装饰器 | 使用位置 | 初始化 | 组件内同步 | 组件外同步 | 父初始化 | 初始化子 | URL | |:-----------------:|:---------:|:---:|:-----:|:---------------------------------------------------:|:-------------------------------:|:-------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------:| | @LocalStorageProp | `组件内`成员变量 | 本地 | Y | LocalStorage -> @LocalStorageProp | 禁止(只能从LocalStorage中key对应的属性初始化) | @State、@Prop、@Link、@Provide | [@LocalStorageProp](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-localstorage.md#localstorageprop) | | @LocalStorageLink | `组件内`成员变量 | 本地 | Y | LocalStorage <-> @LocalStorageLink | 禁止(只能从LocalStorage中key对应的属性初始化) | @State、@Prop、@Link、@Provide | [@LocalStorageLink](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-localstorage.md#localstoragelink) | | @StorageProp | `组件内`成员变量 | 本地 | Y | (Environment -> )AppStorage -> @StorageProp | 禁止(只能从AppStorage中key对应的属性初始化) | @State、@Prop、@Link、@Provide | [@StorageProp](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-appstorage.md#storageprop) | | @StorageLink | `组件内`成员变量 | 本地 | Y | (PersistentStorage <-> )AppStorage <-> @StorageLink | 禁止(只能从AppStorage中key对应的属性初始化) | 无状态、@State、@Prop、@Link、@Provide | [@StorageLink](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-appstorage.md#storagelink) | @ComponentV2 | 装饰器 | 使用位置 | 作用 | URL | |:-------------:|:---------:|:--------:|:-----------------------------------------------------------------------------------------------------------------------:| | AppStorageV2 | `组件内`成员变量 | 应用全局同步 | [AppStorageV2: 应用全局UI状态存储](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-new-appstoragev2-V5) | | PersistenceV2 | `组件内`成员变量 | 持久化存储并同步 | [PersistenceV2: 持久化储存UI状态](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-new-persistencev2-V5) | - 其它状态: @Component | 装饰器 | 使用位置 | 作用 | URL | |:------:|:---------------:|:------------------:|:-----------------------------------------------------------------------------------------------------------------:| | @Watch | `组件内`装饰器装饰的成员变量 | 状态变量更改通知 | [@Watch装饰器:状态变量更改通知](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-watch.md) | | $$ | 支持$$的组件参数/属性 | `部分`变量和`内置`组件双向同步① | [$$语法:内置组件双向同步](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-two-way-sync.md) | | @Track | class对象的成员变量 | class对象属性级更新 | [@Track装饰器:class对象属性级更新](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-track.md) | @ComponentV2 | 装饰器 | 使用位置 | 作用 | URL | |:---------:|:-----------------------------------:|:----------------------------:|:----------------------------------------------------------------------------------------------------------------------------------------:| | @Monitor | `组件内`装饰器装饰的成员变量 | 状态变量更改通知 | [@Monitor装饰器:状态变量修改监听](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-new-monitor-V13) | | !! | 父组件初始化子组件@Param装饰的成员变量 | 简化@Local+@Param+@Event用法 | [!!语法:双向绑定](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-new-binding-V13) | | @Trace | 被@ObservedV2装饰的class对象的成员变量 | 嵌套类对象属性变化直接观测的能力 | [@ObservedV2装饰器和@Trace装饰器:类属性变化观测](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-new-observedv2-and-trace-V13) | | @Computed | `组件内`getter成员方法 | 解决UI多次重用该属性从而重复计算导致的性能问题。 | [@Computed装饰器:计算属性](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-new-computed-V13) | | @Type | 被@ObservedV2装饰的class对象的成员变量的class类型 | 配合PersistenceV2使用,防止序列化时类丢失。 | [@Type装饰器:标记类属性的类型](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-new-type-V13) | 注: 1、所有(状态装饰器装饰的)状态变量都是组件内私有变量,不支持外部访问。 2、组件:这里专指自定义组件。 3、无状态:常规变量。 4、$$两种用法:1)@Builder中按引用传递参数;2)内置组件双向同步。 [PersistentStorage:持久化存储UI状态](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-persiststorage.md) [Environment:设备环境查询](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-environment.md) ①中`部分`是指:当前\$\$支持基础类型变量、以及@State、@Link和@Prop装饰的变量;`内置`是指:[当前$$支持的组件](https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/quick-start/arkts-two-way-sync.md#%E4%BD%BF%E7%94%A8%E8%A7%84%E5%88%99)。 ##### 状态管理(V1) ###### 管理组件拥有的状态 ####### @State装饰器:组件内状态 ####### @Prop装饰器:父子单向同步 ####### @Link装饰器:父子双向同步 ####### @Provide装饰器和@Consume装饰器:与后代组件双向同步 ####### @Observed装饰器和@ObjectLink装饰器:嵌套类对象属性变化 ###### 管理应用拥有的状态 ####### 管理应用拥有的状态概述 ####### LocalStorage:页面级UI状态存储 ####### AppStorage:应用全局的UI状态存储 ####### PersistentStorage:持久化存储UI状态 ####### Environment:设备环境查询 ###### 其他状态管理 ####### 其他状态管理概述 ####### @Watch装饰器:状态变量更改通知 ####### $$语法:内置组件双向同步 ####### @Track装饰器:class对象属性级更新 ###### MVVM模式 ![arkts-mvvm.png](README_PIC%2Farkts-mvvm.png) ###### 状态管理优秀实践 ###### 状态管理合理使用开发指导 ##### 状态管理(V2) ###### V2所属装饰器 ####### @Monitor装饰器:状态变量修改监听 - [当@Monitor定义在@ObservedV2装饰的类中时,@Monitor会在类的`实例创建完成后`生效,在类的实例销毁时失效。](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-new-monitor#类中monitor对变量监听的生效及失效时间) ###### 其他状态管理 ####### !!语法:双向绑定 - $$仍用于状态管理(V2)的`内置`组件双向绑定。 - !!用于状态管理(V2)的`自定义`组件双向绑定。 #### 渲染控制 ##### 渲染控制概述 ##### if/else:条件渲染 ##### ForEach:循环渲染 ##### LazyForEach:数据懒加载 | LazyForEach[接口文档](https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-rendering-control-lazyforeach-V5#接口)说明 | 官方反例 | |:--------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| | itemGenerator中可以使用if语句,但是必须保证if语句每个分支都会创建一个相同类型的子组件。 | [复用组件嵌套结构会变更的场景,使用reuseId标记不同结构的组件构成](https://developer.huawei.com/consumer/cn/doc/best-practices-V5/bpta-component-reuse-V5#section4981115441415) 、 [多种条目类型使用场景](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-reusable-V5#多种条目类型使用场景)、[全局复用](https://gitee.com/openharmony-sig/node_pool) | | itemGenerator中不允许使用ForEach和LazyForEach语句。 | [缓存数据项](https://developer.huawei.com/consumer/cn/doc/best-practices-V5/bpta-swiper_high_performance_development_guide-V5#section143504547145) | | 当数据项在数组中的位置更改时,其键值不得更改 | [渲染结果非预期](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-rendering-control-lazyforeach-V5#渲染结果非预期) | | | 说明 | |:-----------------------:|:-----------------:| | ForEach | 不懒加载、子组件不复用 | | ForEach + @Reusable | 不懒加载、子组件复用 | | LazyForEach | 懒加载 | | LazyForEach + @Reusable | 懒加载、子组件复用 | | Repeat | V2状态下使用,懒加载、子组件复用 | | | ForEach | LazyForEach | |:------------------------------------:|:-------------------------------------------------------------------:|:------------------------------------------------------------------------------------:| | itemGenerator未声明index,涉及arr的增、删、改变顺序 | keyGenerator: (item: Object, index: number) => JSON.stringify(item) | keyGenerator:(item: Object, index: number) => JSON.stringify(item),调用dataSource相关api | | 同上,并且item内部修改 | 同上,并且item对象使用@Observed+@Trace | 同上,并且item对象使用@Observed+@Trace | | itemGenerator声明index | 见【注】中第2条 | 见【注】中第2条 | 注: - 当涉及item对象的数组arr增、删、改变顺序时,keyGenerator: (item: Object, index: number) => JSON.stringify(item)(或者JSON.stringify(item的唯一id))保证itemGenerator不会再次执行。 - 当涉及item对象的数组arr增、删、改变顺序时,itemGenerator的函数体要使用index: - 如果实时显示,则keyGenerator: (item: Object, index: number) => JSON.stringify(item) + index.toString(); - 如果非实时显示(比如点击事件中用到),则不要在itemGenerator声明index使用,而是通过数据源搜索item对应的index使用。 - 当item对象使用@Observed+@Trace,@Trace标注的属性发生变化时,不会比对keyGenerator的返回值,而是重新渲染修改属性对应的组件即可。 - Repeat使用template(type: string, itemBuilder: RepeatItemBuilder, templateOptions?: TemplateOptions)取代itemGenerator, 使用key(keyGenerator: (item: T, index: number) => string)取代keyGenerator。[键值的生成应与index无关](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-new-rendering-control-repeat#键值生成函数)。推荐将简单类型数组转换为类对象数组,并添加一个readonly id属性,在构造函数中初始化唯一值。[当发现有重复key时,Repeat会在已有键值的基础上递归生成新的键值,直到没有重复键值。](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-new-rendering-control-repeat#键值生成函数) ##### Repeat:可复用的循环渲染 - 如果需要添加footer(下拉加载更多),virtualScroll({ totalCount: 不能设置 }),可以写成virtualScroll() - [当需要像ForEach一样加载所有数据时,需要注掉virtualScroll()来关闭懒加载。](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-new-rendering-control-repeat#关闭懒加载) - [template(type: string, itemBuilder: RepeatItemBuilder, templateOptions?: TemplateOptions)中TemplateOptions的cachedCount默认值为屏上容器(比如List)可视节点与预加载节点的个数之和。当cachedCount值被设置为当前template在屏上显示的最大节点数量时,Repeat会做到最大程度的复用。](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-rendering-control-repeat#templateoptions对象说明) # ArkTS(方舟编程语言) ## ArkTS并发 ### 并发概述 并发指在同一时间内,多个任务同时执行: - 多核设备:任务可以在不同CPU上并行执行。 - 单核设备:尽管多个任务不会同时并行,但CPU会在某个任务休眠或进行I/O操作时切换任务,调度其他任务,提高CPU的资源利用率。 并发场景: - 异步并发任务 - 耗时任务(如CPU密集型任务、I/O密集型任务和同步任务等) - 长时任务 - 常驻任务 并发实现方式: - 异步并发:异步代码在执行到一定程度后暂停,并在未来某个时间点继续执行,同一时间只有一段代码执行。ArkTS通过`Promise和async/await`提供异步并发能力,适用于`单次I/O任务`。 - 多线程并发:允许同时执行多段代码。UI主线程响应用户操作和更新UI,后台线程执行耗时操作,避免应用卡顿。ArkTS通过`TaskPool和Worker`提供多线程并发能力,适用于`耗时任务等并发场景`。 - 数据传输方式1:拷贝 - 数据传输方式2:内存共享 ### 异步并发 (Promise和async/await) 使用场景: - I/O非阻塞操作:网络请求、文件读写、定时器等。 - 任务轻量且无CPU阻塞:单次任务执行时间短。 - 逻辑依赖清晰:任务有明确的顺序或并行关系。 ### 多线程并发 #### 多线程并发概述 使用场景: - 大量计算或频繁的I/O读写等需要长时间执行的任务,例如`图片和视频的编解码`、`文件的压缩与解压缩`、`数据库操作`等场景。 - 监听和定期采集数据等需要长时间保持运行的任务,例如`定期采集传感器数据`的场景。 - 业务逻辑跟随主线程的生命周期,或与主线程绑定的任务,例如`在游戏中的业务场景`。 并发模型用于实现不同应用场景中的并发任务。常见的并发模型: - 基于内存共享的模型 - 基于消息通信的模型(Actor并发模型,比如`TaskPool`和`Worker`均基于Actor实现) ### 并发线程间通信 #### ArkTS线程间通信概述 #### 线程间通信对象 ##### 线程间通信对象概述 线程间通信对象必须通过`序列化`实现`值拷贝`或`内存共享`。 - 单次序列化传输的数据量大小限制为16MB。 - 序列化不支持使用@State装饰器、@Prop装饰器、@Link装饰器等装饰器修饰的复杂类型。 目前ArkTS支持线程间通信的对象有以下几种: - 普通对象:可直接传递基本数据类型及自定义对象(需满足序列化规范)。 - ArrayBuffer对象:用于二进制数据的高效传递,适用于大段连续内存数据(如图片、音频原始数据)。 - SharedArrayBuffer对象:支持多线程共享内存,允许线程间直接访问同一块内存区域,提升数据传递效率。 - Transferable对象(NativeBinding对象):支持跨线程转移对象所有权(如文件描述符、图形资源等),转移后原线程不再拥有访问权限。 - Sendable对象:符合ArkTS语言规范的可共享对象,需通过@Sendable装饰器标记,并且满足Sendable约束,详情可查Sendable使用规则与约束。 ##### Sendable对象 ## ArkTS运行时 ### ArkTS模块化 #### 动态加载 ##### HAR模块间动态import依赖解耦 跨模块同步方式: - 加载UI组件:参见下面【设置组件导航和页面路由】 - 两者都是UI组件:@Provider/@Consumer(浅拷贝) - 允许非UI组件:AppStorageV2(浅拷贝,类需要声明在共享模块中) - 允许非UI组件 & 持久化:PersistenceV2(深拷贝,类需要声明在共享模块中) - 允许非UI组件(线程内通信):EventHub(浅拷贝,如果涉及状态变量,使用 AppStorageV2 更方便) - 线程间通信:Emitter(深拷贝,不用需取消订阅) - [动态import(仅限本地源码HAR包之间形成循环依赖时使用)](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-dynamic-import-V5#har模块间动态import依赖解耦) - 共享模块 # ArkUI(方舟UI框架) ## UI开发(ArkTS声明式开发范式) ### 设置组件导航和页面路由 | 页面跳转 | Navigation | router | |:----:|:--------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------:| | 同包 | import <页面Path> + navDestination(...) + NavPathStack.xxxPath({name: '...' }) | 页面注解@Entry + 页面在main_pages.json中声明 + router.xxxUrl({url: <页面Path>}) | | 跨包 | 跨包动态路由之系统路由表: 页面配置@Builder全局函数 + 页面在route_map.json中声明 + NavPathStack.xxxPath({name: '...' }) | 命名路由:页面注解@Entry({ routeName: '...' }) + oh-package.json5中配置包依赖 + import <页面Path> + router.xxxNamedRoute({name: <页面名称>}) | | | 跨包动态路由之自定义路由表:[HMRouter](https://ohpm.openharmony.cn/#/cn/detail/@hadss%2Fhmrouter) | | [Navigation传递参数性能更优,Navigation通过引用传递,Router通过深拷贝完成;](https://developer.huawei.com/consumer/cn/forum/topic/0204150545294348010) ### 使用弹窗 #### 弹窗概述 模态弹窗:强交互,中断用户当前的操作流程。一般有半透明蒙层。 弹出框(Dialog):二次退出应用 菜单控制(Menu):长按图标展示操作选项 气泡提示(Popup):点击一个问号图标弹出一段帮助提示 绑定模态页面:缩略图片点击后查看大图 非模态弹窗:弱交互,不中断用户当前的操作流程,通常一段时间消失。 弹出框(Dialog) 菜单控制(Menu) 气泡提示(Popup) 即时反馈(Toast):提示文件保存成功 浮层(OverlayManager):音乐/语音播放悬浮球/胶囊 #### 使用弹出框 (Dialog) ##### 弹出框概述 自定义弹出框 不依赖UI组件的全局自定义弹出框 (openCustomDialog):由于 基础自定义弹出框 在使用上存在诸多限制,不支持动态创建也不支持动态刷新,所以推荐用这个。 基础自定义弹出框 (CustomDialog)【不推荐】:NavDestination设置弹窗类型来代替:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-navigation-navigation-V5#%E9%A1%B5%E9%9D%A2%E6%98%BE%E7%A4%BA%E7%B1%BB%E5%9E%8B 固定样式弹出框:警告弹窗、列表选择弹窗、选择器弹窗、对话框、操作菜单 #### 绑定模态页面 ##### 绑定模态页面概述 半模态(bindSheet):分享框 全模态(bindContentCover):缩略图片点击后查看大图 ##### 绑定半模态页面(bindSheet) - API 15 后支持 radius 调整圆角大小。 ### 使用动画 #### 转场动画 ##### 模态转场 模态转场是新的界面覆盖在旧的界面上,旧的界面不消失的一种转场方式。原来在Android上可能需要使用Dialog或新页面做的事情,在这里只需要在原界面上做。 - 使用bindContentCover构建全屏模态转场效果 - 使用bindSheet构建半模态转场效果 - 使用bindMenu实现菜单弹出效果 - 使用bindContextMenu实现菜单弹出效果 - 使用bindPopUp实现气泡弹窗效果 - 使用if实现模态转场 ### 支持交互事件 #### 交互事件概述 #### 使用通用事件 ##### 事件分发 事件分发是指通过触摸测试,来收集需要响应触屏事件的组件,再基于触摸测试结果分发相应的触屏事件。 触摸测试决定这个触控事件由哪个节点消费。 - hitTestBehavior:[触摸测试控制](https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-universal-attributes-hit-test-behavior-V5) - HitTestMode.Default:自身和子节点都响应触摸测试,阻塞兄弟节点的触摸测试。不会影响祖先节点的触摸测试。 - HitTestMode.Block:自身响应触摸测试,阻塞子节点和兄弟节点的触摸测试。会阻塞祖先节点的触摸测试。 - HitTestMode.Transparent:自身和子节点都响应触摸测试,不会阻塞兄弟节点的触摸测试。不会影响祖先节点的触摸测试。 - HitTestMode.None:自身不响应触摸测试,不会阻塞子节点和兄弟节点的触摸测试。不会影响祖先节点的触摸测试。 - interceptTouch:[自定义事件拦截](https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-universal-attributes-on-touch-intercept-V5) - responseRegion:[触摸热区设置](https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-universal-attributes-touch-target-V5) - enabled:[禁用控制](https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-universal-attributes-enable-V5) - 安全组件 - 其他属性设置:透明度/组件下线 接收到起始事件后,系统将自上而下、自右向左(按组件布局的先后层级)遍历组件树,收集每个组件上绑定的手势和事件,然后将这些信息逐级向上冒泡至父组件进行整合,最终构建完整的事件响应链。 [自定义事件分发](https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-universal-attributes-on-child-touch-test-V5):在父节点,开发者可以通过onChildTouchTest决定如何让子节点去做触摸测试,影响子组件的触摸测试,最终影响后续的触屏事件分发。 #### 使用手势事件 [手势事件冲突解决方案](https://developer.huawei.com/consumer/cn/doc/best-practices-V5/bpta-gestures-practice-V5)中常见手势冲突问题解决方案: - 滚动容器嵌套滚动容器事件冲突:nestedScroll - 使用组合手势同时绑定多个同类型手势冲突:GestureMode - 系统手势和自定义手势之间冲突:priorityGesture - 手势事件透传:hitTestBehavior - 多点触控场景下手势冲突:monopolizeEvents - 动态控制自定义手势是否响应:onGestureJudgeBegin - 父组件如何管理子组件手势:shouldBuiltInRecognizerParallelWith和onGestureRecognizerJudgeBegin ##### 绑定手势方法 - gesture(常规手势绑定方法) - priorityGesture(带优先级的手势绑定方法) - parallelGesture(并行手势绑定方法) ##### 单一手势 - 点击手势(TapGesture) - 长按手势(LongPressGesture) - 拖动手势(PanGesture) - 捏合手势(PinchGesture) - 旋转手势(RotationGesture) - 滑动手势(SwipeGesture) ##### 组合手势 - 顺序识别:GestureMode.Sequence - 并行识别:GestureMode.Parallel - 互斥识别:GestureMode.Exclusive ##### 多层级手势事件 当父子组件均绑定同一类手势时,子组件优先于父组件触发。 手势和事件的控制方法: - responseRegion:影响手势和事件 - hitTestBehavior:通过影响事件(onTouch)来影响手势 - 绑定手势方法:通过gesture、priorityGesture、parallelGesture来影响手势 ##### 手势拦截 手势拦截主要采用以下两种方式实现: - 手势触发控制 - onGestureJudgeBegin:用于手势拦截,是通用事件。在手势满足系统触发阈值场景下,回调给应用判断是否拦截手势。 - onGestureRecognizerJudgeBegin:用于手势拦截、获取手势识别器和初始化手势识别器开闭状态。是onGestureJudgeBegin接口的能力扩展。获取手势识别器时,会获取一次交互中手势响应链上的所有手势识别器,以及当前即将触发的手势识别器,初始化手势的激活状态。 - 手势响应控制 - shouldBuiltInRecognizerParallelWith:用于设置系统原生组件内置手势与其他手势并行。 - onGestureRecognizerJudgeBegin:用于手势拦截,获取手势识别器,初始化手势识别器开闭状态。 - parallelGesture:可使开发者定义的手势,与比他优先级高的手势并行。 PS: [自定义手势判定](https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-gesture-customize-judge-V5) [手势拦截增强](https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-gesture-blocking-enhancement-V5) ### 使用自定义能力 #### 自定义扩展 ##### 属性更新器 (AttributeUpdater) - 不要使用 @Param 从外部传入 AttributeUpdater 无效,原因未知。 - [精准控制组件属性的刷新,避免组件不必要的属性刷新。](https://developer.huawei.com/consumer/cn/doc/best-practices-V5/bpta-component-reuse-V5#section4470171391314) # [空白与分隔](https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/blank-space-and-separation-V5) | | Blank | Divider | |:---:|:----------------------------------------------:|:---------------:| | 父控件 | Row/Column/Flex | 无限制 | | 长度 | 除非固定长度,否则撑满容器交叉轴(即alignSelf为ItemAlign.Stretch) | 除非固定长度,否则就是贯通屏幕 | ## Blank - 仅当父组件为Row/Column/Flex时生效 - color:颜色,而非 backgroundColor - 支持通用事件 ## Divider - vertical:方向 - color:颜色,而非 backgroundColor - strokeWidth:粗细,而非 width/height