2025年HarmonyOS面试题

请简述鸿蒙OS与Android OS的主要区别是什么?

  • 分布式架构:HarmonyOS支持跨设备无缝协作,允许设备之间共享硬件资源。
  • 性能:HarmonyOS优化了任务调度和内存管理,提高了性能和响应速度。
  • 安全性:HarmonyOS采用了多层次的安全策略,包括数据加密和安全启动。
  • 生态系统:HarmonyOS正在构建自己的应用生态系统,鼓励开发者使用Ark Ts和ArkUI框架。

HarmonyOS应用打包后的文件扩展名是?

打包后的文件扩展名为.hap(HarmonyOS Ability Package),这是HarmonyOS应用的标准包格式

ArkTs是什么?

ArkTS是HarmonyOS优选的主力应用开发语言。保持了TypeScript的基本风格,同时通过规范定义强化开发期静态检查和分析,提升程序执行稳定性和性能。

ArkTS的主要特点包括:

静态类型检查: ArkTS在编译时进行类型检查,这有助于在代码运行前发现和修复错误,提高代码的稳定性和性能。

声明式UI: ArkTS定义了声明式UI描述,允许开发者以更简洁、更自然的方式开发跨端应用。

状态管理: ArkTS提供了多维度的状态管理机制,使得与UI相关联的数据可以在组件内使用,也可以在不同组件层级间传递,支持单向和双向数据流。

渲染控制: ArkTS支持条件渲染、循环渲染和数据懒加载,允许开发者根据应用的不同状态渲染UI内容。

兼容性: ArkTS兼容TS/JavaScript生态,开发者可以使用TS/JS进行开发或复用已有代码。

并发机制: ArkTS支持轻量化的并发机制,允许开发者编写并发代码,提高应用的性能和响应速度。

ArkTs 和 Ts 有什么区别

ArkTs 基于 Ts 做了扩展,并且强化了静态检查和分析

一、扩展了 UI:

  • 定义了声明式 UI 描述、自定义组件,事件方法、属性方法
  • 提供了多维度的状态管理机制
  • 提供了控制渲染、循环渲染的能力

二、强化了检查

  • 不支持 var、any、unknown、Symbol
  • 不支持解构赋值
  • 不支持使用对象字面量进行类型声明
  • 不支持在运行时动态增删对象的属性
  • 不支持在函数内声明函数
  • 不支持使用 typeof 作为类型
  • 不支持使用 # 符号开头声明的私有字段,改用 private 关键字
  • 不支持把 function 定义函数赋值给变量,改为使用箭头函数

页面和自定义组件生命周期有哪些?

页面生命周期,即被@Entry装饰的组件生命周期,提供以下生命周期接口:

  • onPageShow:页面每次显示时触发一次,包括路由过程、应用进入前台等场景。
  • onPageHide:页面每次隐藏时触发一次,包括路由过程、应用进入后台等场景。
  • onBackPress:当用户点击返回按钮时触发。

组件生命周期,即一般用@Component装饰的自定义组件的生命周期,提供以下生命周期接口:

  • aboutToAppear:组件即将出现时回调该接口,具体时机为在创建自定义组件的新实例后,在执行其build()函数之前执行。
  • onDidBuild:组件build()函数执行完成之后回调该接口,开发者可以在这个阶段进行埋点数据上报等不影响实际UI的功能。不建议在onDidBuild函数中更改状态变量、使用animateTo等功能,这可能会导致不稳定的UI表现。
  • aboutToDisappear:aboutToDisappear函数在自定义组件析构销毁之前执行。不允许在aboutToDisappear函数中改变状态变量,特别是@Link变量的修改可能会导致应用程序行为不稳定。

生命周期流程如下图所示,下图展示的是被@Entry装饰的组件(页面)生命周期。

如何进行数据持久化?

  • 用户首选项(Preferences):这是一种轻量级的配置数据持久化方式,适用于保存应用配置信息、用户偏好设置等。它通过文本形式保存数据,并且数据会全量加载到内存中,因此访问速度快,但不适合存储大量数据。
  • 键值型数据库(KV-Store):适用于存储结构简单的数据,如商品名称和价格、员工工号和出勤状态等。键值型数据库以“键值对”的形式组织数据,适合数据关系不复杂的场景。
  • 关系型数据库(RelationalStore):基于SQLite,适用于存储包含复杂关系的数据,如学生信息、雇员信息等。关系型数据库提供了一系列SQL操作,如增删改查等。

父子组件如何通信?

当前(API 12)状态管理有两个版本 @Component和 @ComponentV2

父子单向数据传递 @State @Prop

  • @Prop装饰的变量可以和父组件建立单向的同步关系。@Prop装饰的变量是可变的,但是变化不会同步回其父组件。

父子双向数据传递 @State @Link 、@objectLink @Link

  • 子组件中被 @Link装饰的变量与其父组件中对应的数据源建立双向数据绑定。

跨组件通信 @Provide装饰器和 @Consume装饰器

  • @Provide和 @Consume,应用于与后代组件的双向数据同步,应用于状态数据在多个层级之间传递的场景。不同于 @Prop和 @Link,@Provide和 @Consume摆脱参数传递机制的束缚,实现跨层级传递。

@Observed装饰器和 @ObjectLink装饰器

  • 对于多层嵌套的情况,比如二维数组,或者数组项class,或者class的属性是class,他们的第二层的属性变化是无法观察到的。这就要用到 @Observed/@ObjectLink装饰器

注意:@ObjectLink装饰器不能在 @Entry装饰的自定义组件中使用且 @ObjectLink 装饰的变量不能被赋值,只能对其属性进行赋值操作

兄弟组件如何通信?

通过公共父组件传递

如果两个组件是同一个父组件的子组件,可以通过父组件来传递数据或事件。父组件可以作为中介,将一个子组件的数据或事件传递给另一个子组件。

使用全局状态管理

使用全局状态管理(如 AppStorage、LocalStorage)来存储共享数据。兄弟组件可以独立地读取和更新这个全局状态,从而实现通信。

如何实现页面间的通信?

  • 使用 @Provide和 @Consume装饰器(见6.3)
  • 使用路由跳转传参
  • 使用导航跳转传参

跨设备通信的方式有哪些?

HarmonyOS支持多种跨设备通信方式,包括:

  • 分布式软总线:一种高性能的通信机制,允许设备之间建立直接连接,进行数据传输。
  • 蓝牙:使用标准的蓝牙技术进行设备间的通信。
  • WLAN:通过WLAN网络实现设备间的通信。
  • 远程服务调用:通过分布式任务调度实现跨设备的服务调用。

如何进行全局状态管理?

@Provide @Consume装饰器

  • 适用场景:适用于整个组件树而言“全局”的状态共享,且该状态改动不频繁的场景。
  • 工作原理:通过在最顶层组件中使用 @Provide装饰器提供状态,其他需要共享状态的组件通过 @Consume装饰器获取该状态 。
  • 优点:减少了状态传递的层级,提升了代码的可维护性和可拓展性。
  • 注意事项:确保状态的生命周期与组件树的生命周期一致,避免不必要的UI刷新。

AppStorage

  • 适用场景:适用于整个应用而言“全局”的变量或应用的主线程内多个 UIAbility实例间的状态共享。
  • 工作原理:AppStorage与应用的进程绑定,由UI框架在应用程序启动时创建,当应用进程终止,AppStorage被回收。
  • 优点:适用于需要在整个应用中-共享状态的场景。
  • 注意事项:确保状态的生命周期与应用进程一致,避免在应用退出后仍有状态存在。

LocalStorage

  • 适用场景:适用于单个Ability而言“全局”的变量,主要用于不同页面间的状态共享。
  • 工作原理:LocalStorage的生命周期由应用程序决定,当应用释放最后一个指向 LocalStorage的引用时,LocalStorage被垃圾回收。
  • 优点:适用于需要在单个UIAbility中不同页面间共享状态的场景。
  • 注意事项:确保状态的生命周期与应用程序的生命周期一致,避免在应用退出后仍有状态存在。

LocalStorage在应用重启后数据会消失吗?

会,因为LocalStorage 是一种用于页面或组件级别的数据存储方式,它允许开发者在页面或组件的生命周期内存储和检索数据。LocalStorage 的数据存储在内存中,因此它的读写速度相对较快。但是,当应用重启后,LocalStorage 中的数据会丢失。

Navigation组件跳转和router跳转有什么区别?

  • Navigation:是路由容器组件,适用于模块内和跨模块的路由切换,一次开发,多端部署场景。Router位于页面栈管理节点 stage 下面,不提供导航容器的概念。
  • Navigation和 Router都支持跳转传参,但 Router对象中暂不支持方法变量。
  • Navigation:支持清理指定路由,页面栈没有上限,可以无限跳转。Router不支持清理指定路由且页面栈最大为32,页面栈到达32之后必须清除之后才能继续跳转。
  • Navigation:支持自定义转场动画和共享元素转场动画。 Router:仅支持简单自定义转场动画。
  • Navigation:支持通过 setInterception 方法设置路由拦截。Router:不支持路由拦截。
  • Navigation:支持沉浸式页面和模态嵌套路由。Router:不支持,需要通过窗口配置实现沉浸式页面。

总而言之,Navigation 组件在功能上更具丰富性和灵活性,特别是在处理复杂的导航结构、动效和路由管理方面。

而 Router 则提供了更基础的路由跳转功能,适合简单的路由需求。开发者可以根据应用的具体需求和设计选择最合适的路由方案

鸿蒙有哪些后台任务类型

OpenHarmony标准系统支持规范内受约束的后台任务,包括短时任务、长时任务、延迟任务、代理提醒和能效资源。

开发者可以根据如下功能介绍,选择合适的后台任务以满足应用退至后台后继续运行的需求。

  • 短时任务:适用于实时性要求高、耗时不长的任务,例如状态保存。
  • 长时任务:适用于长时间运行在后台、用户可感知的任务,例如后台播放音乐、导航、设备连接等,使用长时任务避免应用进程被挂起。
  • 延迟任务:对于实时性要求不高、可延迟执行的任务,系统提供了延迟任务,即满足条件的应用退至后台后被放入执行队列,系统会根据内存、功耗等统一调度。
  • 代理提醒:代理提醒是指应用退后台或进程终止后,系统会代理应用做相应的提醒。适用于定时提醒类业务,当前支持的提醒类型包括倒计时、日历和闹钟三类。

如何实现应用的后台运行?

  • 后台服务: 使用后台服务(如BackgroundService)来执行不需要用户直接交互的任务。
  • 定时任务: 通过系统提供的定时任务机制(如AlarmService)来周期性执行后台任务。
  • 事件监听: 注册系统事件,如网络变化、电量变化等,以在特定事件发生时唤醒应用进行处理。

什么是Ability?

Ability是应用/服务所具备的能力的抽象,一个Module可以包含一个或多个 Ability ,在鸿蒙系统中,Ability提供了对 Ability生命周期、上下文环境等调用管理的能力,包括 Ability创建、销毁、转储客户端信息等

鸿蒙系统中的 Ability主要分为两种类型:UIAbility和 ExtensionAbility。

UIAbility :

  • 定义 :包含UI界面,提供展示UI的能力,主要用于和用户交互 。
  • 创建 :在模块中添加UIAbility时,选中对应的模块,单击鼠标右键,选择New > Ability,设置Ability名称,选择是否在设备主屏幕上显示该功能的启动图标,单击Finish完成Ability创建 。

ExtensionAbility :

  • 定义 :提供特定场景的扩展能力,满足更多的使用场景 。
  • 创建 :在模块中添加ExtensionAbility时,选中对应的模块,单击鼠标右键,选择不同的场景类型(如Accessibility、EmbeddedUIExtensionAbility等) 。当前仅Application工程支持创建ExtensionAbility。设置Ability名称,单击Finish完成ExtensionAbility创建。
  • 此外,Ability是Ability模块的基类,提供系统配置更新回调和系统内存调整回调 。Ability的继承关系包括UIAbility和ExtensionAbility等具体类.

总之,Ability是鸿蒙系统中用于管理应用能力的核心组件,通过不同类型的Ability可以实现不同的功能需求。

请介绍UIAbility的启动模式

UIAbility的启动模式是指在启动UIAbility实例时所采用的不同呈现状态和行为方式。HarmonyOS为UIAbility提供了多种启动模式,以满足不同业务场景的需求。这些启动模式包括:

  1. Singleton(单实例模式) :这是默认情况下的启动模式。当应用进程中该类型的UIAbility实例已经存在时,系统会复用该实例,而不是创建新的实例。这意味着每次调用startAbility()方法时,如果相同类型的UIAbility实例已经存在,则不会进入onCreate()和onWindowStageCreate()生命周期回调,而只会进入onNewWant()回调。这种模式下,UIAbility在任务列表里只会有一个历史任务。
  2. Multiton(多实例模式) :在这种模式下,可以多次创建UIAbility实例。但是,每次创建新的实例之前,之前的实例都会被销毁。因此,在任务列表里也只能看到一个历史任务。每次创建新的实例时,都会重新走一遍UIAbility的生命周期方法。
  3. Standard(标准实例模式) :这也是一种多实例模式。与Multiton不同的是,创建新的实例时不会销毁之前的实例,所以在任务列表里可以看到多个实例。这意味着每次点击都会创建新的实例,并且每个实例都有自己的生命周期。
  4. Specified(指定实例模式) :这种启动模式需要指定一个ID。在创建UIAbility时,系统会先判断任务列表里是否存在指定ID的UIAbility实例。如果存在,则不会创建新的实例;如果不存在,则会创建新的实例。

Ability是如何与用户交互的?

  • 界面显示:Ability可以包含一个或多个AbilitySlice,用于显示UI界面并与用户进行交互。
  • 事件处理:Ability可以处理用户的输入事件,如触摸、按键等。
  • 数据绑定:Ability可以使用数据绑定机制,将UI组件与数据模型绑定,实现数据的自动更新和交互。
  • 通知:Ability可以通过系统通知机制向用户发送通知,即使应用不在前台运行。

如何实现应用的多语言支持?

  • 资源文件:为每种语言创建资源文件(如string.json),并在里面定义所有可本地化的字符串。
  • 资源引用:在代码中使用资源ID引用字符串,而不是硬编码文本。
  • 系统设置:应用会自动根据系统设置的语言环境加载相应的资源文件。
  • 动态切换:支持在应用运行时切换语言,并动态更新UI。

分布式数据库是如何实现数据同步的?

  • 分布式事务:确保跨设备的数据库操作具有原子性、一致性、隔离性和持久性。
  • 数据版本控制:为数据添加版本号,确保同步时数据的一致性。
  • 冲突解决策略:定义冲突解决策略,处理并发操作导致的数据冲突。
  • 网络状态感知:根据网络状态智能同步数据,优化同步效率和流量使用。

如何优化应用的性能?

一、使用并行化、预加载和缓存等方法,提升系统资源利用率,减少主线程负载,加快应用的启动速度和响应速。

  • 使用多线程执行耗时操作
  • 使用异步执行耗时操作
  • 使用预加载提升页面启动和响应速度
  • 使用条件渲染实现预加载
  • 使用缓存提升启动速度和滑动帧率

二、尽量减少布局的嵌套层数

  • 移除冗余节点,删除无用的Stack/Column/Row嵌套
  • 使用Column/Row替代Flex构建线性布局
  • 使用Flex、List、Grid、RelativeContainer、绝对布局和自定义布局等构建复杂布局

三、合理管理状态变量

  • 合理管理状态变量,减少不必要的参数层次传递
  • 避免滥用@Provide+@Consume
  • 控制对象级状态变量成员数量
  • 避免不必要的创建和读取状态变量

四、合理使用系统接口,避免冗余操作

  • 避免在系统高频调用进行冗余和耗时操作
  • 避免在系统高频调用打印日志
  • 在Release版本中删除Debug日志

五、使用性能工具分析和定位问题

HarmonyOS中的权限管理模型是怎样的?

  • 权限声明:应用在config.json中声明所需的权限。
  • 权限申请:在应用运行时,根据需要动态申请权限。
  • 权限检查:在执行敏感操作前,检查是否已获得相应权限。
  • 权限分组:系统将权限分为不同的组,便于管理和申请。

LazyForEach是什么?

  • LazyForEach 是一个用于高效渲染列表的组件或功能。
  • 它允许开发者在用户滚动列表时才加载和渲染列表项,而不是一次性渲染整个列表。
  • 这种按需渲染的方式可以显著提高应用的性能,特别是在处理大量数据时。

LazyForEach的工作原理是什么?

LazyForEach 的工作原理通常是基于用户的滚动位置来动态地创建和销毁列表项的组件实例。当用户滚动到列表的某个部分时,LazyForEach 会加载并渲染那些即将进入视图的列表项,同时可能会卸载那些滚出视图的列表项,以节省内存和计算资源。

Router.replace()方法的作用是什么?和Router.pushUrl()方法有什么区别?

Router.replace()方法用于替换当前路由,并将目标路由压入栈顶。与Router.pushUrl()方法不同,Router.replace()方法不会保留当前路由,而是直接替换掉当前路由。

如何实现应用的沉浸式模式?

沉浸式模式是指应用界面呈现出沉浸式的全屏模式,不留任何系统UI,用户只能看到应用内容。在沉浸式模式下,应用的UI元素会被覆盖,但系统状态栏、导航栏、键盘等系统UI依然可见。以下是实现步骤

  1. 设置窗口属性:

在应用的入口Ability中,可以通过设置窗口属性来实现沉浸式模式。这通常涉及到配置窗口特性(Window Features)来隐藏状态栏和导航栏。

  1. 使用系统API:

鸿蒙OS提供了API来控制系统UI的显示和隐藏。你可以在应用的代码中调用这些API来实现沉浸式效果。

  1. 配置应用的配置文件:

在应用的config.json或其他配置文件中,可以声明应用需要的窗口特性,如ohos:immersive。

  1. 动态切换:

应用可以根据用户的交互或特定场景动态地进入或退出沉浸式模式。这可能涉及到监听用户的手势或其他事件来切换UI状态。

  1. 适配不同设备:

不同的设备可能有不同的屏幕和系统UI,因此在实现沉浸式模式时,需要考虑不同设备的适配问题。

如何获取屏幕的安全区域?

可以通过设置组件的expandSafeArea属性来获取获取UIWindow:首先,你需要获取到当前页面的UIWindow实例。

调用getSafeArea方法:通过UIWindow实例调用getSafeArea方法来获取安全区域的Rect对象。

@Prop和@ObjectLink装饰器有什么区别?

  1. 用途

@Prop装饰器:主要用于在组件之间传递数据,将父组件的值传递给子组件。它定义了子组件的属性,可以接收来自父组件的赋值。

@ObjectLink用于建立对象之间的链接,通常用于在组件内部或组件之间共享和同步状态。它可以将一个对象的属性与另一个对象的属性进行链接,当一个对象的属性发生变化时,另一个对象的属性也会自动更新。

  1. 数据传递方式

@Prop:是单向的数据传递,从父组件到子组件。父组件可以设置子组件的 @Prop属性值,但子组件不能直接修改这个值。

@ObjectLink是双向的数据传递,父组件和子组件都可以修改子组件的 @ObjectLink属性值。

  1. 性能

@Prop会深拷贝数据,具有拷贝的性能开销,性能低于 @ObjectLink

ForEach和LazyForEach的区别?

ForEach和LazyForEach都是用于渲染列表的装饰器,它们的区别在于:

  • ForEach:渲染列表时,会将列表中的每一项都渲染一次,适用于列表项数量较少的情况。
  • LazyForEach:渲染列表时,只渲染当前可见的列表项,适用于列表项数量较多的情况。

H5如何与HarmonyOS应用(webView)进行通信?

应用调用H5页面JS函数

应用侧可以通过runj()方法异步调用前端页面的j相关函数,并通过Promise方式返回脚本执行的结果。runj需要在loadUrl完成后,比如onPageEnd中调用。

H5页面调用应用函数

使用Web组件将应用侧代码注册到前端页面中,注册完成之后,前端页面中使用注册的对象名称就可以调用应用侧的函数,实现在前端页面中调用应用侧方法。注册应用侧代码有两种方式,一种在Web组件初始化调用,使用jProxy()接口。另外一种在Web组件初始化完成后调用,使用registerjProxy()接口。

Hap、Har、Hsp 分别是什么,它的特点及其应用场景?

这三个都是 HarmonyOS 中的三种不同类型的构建产物,它们在鸿蒙系统中有着不同的作用和特点

HAP

HAP(Harmony Ability Package)是应用安装和运行的基本单元。可以被单独安装和运行。(又称ability)其主要分为两种类型:entry和feature。

  • entry:应用的主模块,作为应用的入口,提供了应用的基础功能。
  • feature:应用的动态特性模块,作为应用能力的扩展,可以根据用户的需求和设备类型进行选择性安装。

HAR

HAR(Harmony Archive)是静态共享包,可以包含代码、C++库、资源和配置文件。通过HAR可以实现多个模块或多个工程共享ArkUI组件、资源等相关代码。(又称static library, 静态共享包)

  • 通过 Static Library 类型的 Model 构建来的
  • 编译时会被打包进使用到它 Hap/Hsp 包中
  • 多包引用相同的 Har 包时,会造成多包间代码和资源的重复

HSP

HSP(Harmony Shared Package)是动态共享包,可以包含代码、C++库、资源和配置文件,通过HSP可以实现代码和资源的共享。HSP不支持独立发布,而是跟随其宿主应用的APP包一起发布,与宿主应用同进程,具有相同的包名和生命周期。

  • 通过 Shared Library 类型的 Model 构建来的
  • 不会被打包进使用它的 Hap/Hsp 包,而是单独存在
  • 当多包需要同时引用同一个共享包时,可以采用 Hsp 替代 Har,能避免 Har 造成的多包间代码和资源的重复拷贝,从而减小应用包大小
  • HSP不支持在设备上单独安装/运行,需要与依赖该HSP的HAP一起安装/运行。HSP的版本号必须与HAP版本号一致。
  • HSP不支持在配置文件中声明ExtensionAbility组件,但支持UIAbility(除入口ability外)组件。
  • HSP可以依赖其他HAR或HSP,但不支持循环依赖,也不支持依赖传递。

image.png

image.png

build() 函数内的语法需要遵守什么限制?

  • @Entry装饰的自定义组件,其 build() 函数下的根节点唯一且必要,且必须为容器组件
  • @Component装饰的自定义组件,其 build() 函数下的根节点唯一且必要,可以为非容器组件
  • ForEach 禁止作为根节点
  • 不允许使用 switch 语法
  • 避免直接在 Text 组件内改变 count 的值
  • 不允许调用没有用 @Builder 装饰的方法
  • 不允许声明本地变量
  • 不允许创建本地作用域
  • 不允许 console.info 之类的语句

鸿蒙常用的装饰器有哪些?

  1. @Entry:用于标记页面的入口点,必须声明在页面的主结构上。
  2. @Component:用于声明页面或子组件的构建结构。
  3. @State:用于声明组件内的可变状态,当状态值改变时,UI将自动重新渲染。
  4. @Link:用于父组件与子组件之间的双向绑定,允许子组件更新父组件中的数据。
  5. @Prop:用于创建父子组件间的单向数据绑定,父组件的状态变化会同步到子组件的@Prop变量,但子组件的@Prop变量的修改不会同步回父组件。
  6. @Provide 和  @Consume:应用于与后代组件的双向数据同步,实现跨层级传递。
  7. @Observed 和  @ObjectLink:用于在涉及嵌套对象或数组的场景中进行双向数据同步。
  8. @LocalStorageProp 和  @LocalStorageLink:与LocalStorage中给定属性建立同步关系。
  9. @StorageProp 和  @StorageLink:与应用级状态存储建立同步关系。
  10. @Watch:用于监听数据变化。
  11. @Styles:用于定义组件的样式。
  12. @Extend:用于扩展其他组件。
  13. @Concurrent:用于声明并发执行的方法

对于一些公共的样式你是怎么做的?有没有什么优化的方式

  • 封装组件
  • 提取Builder
  • 提取Styles和Extends

Styles和Extend两个装饰器的区别?

鸿蒙OS中的@Styles@Extend两个装饰器都用于样式复用,但它们之间存在一些关键区别:

  1. 定义范围: @Styles装饰器可以在全局或组件内部定义,而@Extend装饰器仅支持在全局定义,不支持在组件内部定义。

  2. 私有属性和事件@Extend支持封装指定组件的私有属性和私有事件,以及预定义相同组件的@Extend方法,而@Styles仅支持通用属性和通用事件。

  3. 参数支持@Extend装饰的方法支持参数,允许开发者在调用时传递参数,遵循TypeScript方法传值调用。相比之下,@Styles方法不支持参数。

  4. 事件句柄: @Extend装饰的方法参数可以是函数,作为事件的句柄,而@Styles不支持这一点。

  5. 状态变量@Extend的参数可以是状态变量,当状态变量改变时,UI可以正常被刷新渲染,而@Styles不支持状态变量作为参数。

  6. 样式复用: @Styles用于快速定义并复用自定义样式,适合提炼公共样式进行复用,而@Extend用于扩展原生组件样式,提供了更多的灵活性和扩展性。

什么是三层工程结构?一次开发,多端部署

  • common(公共能力层):用于存放公共基础能力集合(如工具库、公共配置等)。

    common层可编译成一个或多个HAR包或HSP包(HAR中的代码和资源跟随使用方编译,如果有多个使用方,它们的编译产物中会存在多份相同拷贝;而HSP中的代码和资源可以独立编译,运行时在一个进程中代码也只会存在一份),其只可以被products和features依赖,不可以反向依赖。

  • features(基础特性层):用于存放基础特性集合(如应用中相对独立的各个功能的UI及业务逻辑实现等)。

    各个feature高内聚、低耦合、可定制,供产品灵活部署。不需要单独部署的feature通常编译为HAR包或HSP包,供products或其它feature使用,但是不能反向依赖products层。需要单独部署的feature通常编译为Feature类型的HAP包,和products下Entry类型的HAP包进行组合部署。features层可以横向调用及依赖common层。

  • products(产品定制层):用于针对不同设备形态进行功能和特性集成。

    products层各个子目录各自编译为一个Entry类型的HAP包,作为应用主入口。products层不可以横向调用。

在ArkTS中,V1和V2版本的装饰器存在哪些区别?

状态管理装饰器

  • V1版本中,主要使用@State装饰器来定义组件中的状态变量,当状态变量变化时,会触发UI刷新。
  • V2版本中,引入了更多的状态变量装饰器,包括@Local@Param@Once@Event@Provider@Consumer等,以支持更细粒度的状态管理和更复杂的组件交互。例如,@Local表示组件内部的状态,使得自定义组件内部的变量具有观测变化的能力,并且只能从组件内部初始化。

组件装饰器

  • V1版本中,使用@Component装饰器来定义自定义组件。
  • V2版本中,引入了@ComponentV2装饰器,它允许使用全新的状态变量装饰器,并且不支持组件复用、LocalStorage等现有自定义组件的能力。同时,@ComponentV2支持一个可选的boolean类型参数freezeWhenInactive,来实现组件冻结功能。

事件装饰器:V2版本中,新增了@Event装饰器,用于规范组件输出,允许子组件向父组件要求更新@Param装饰变量的能力。@Event主要配合@Param实现数据的双向同步。

提供和消费装饰器:V2版本中,@Provide@Consume装饰器用于与后代组件的双向数据同步,适用于状态数据在多个层级之间传递的场景。@Provide作为数据的提供方,可以更新其子孙节点的数据,并触发页面渲染。@Consume在感知到@Provide数据的更新后,会触发当前自定义组件的重新渲染。

观察变化的装饰器:V2版本中,@Observed@ObjectLink装饰器用于观察嵌套对象的变化,这对于多层嵌套的数据结构特别有用。@Observed用于修饰类,使得可以观察到嵌套的变化;@ObjectLink用在子组件中,用于接收@Observed装饰的类的实例,并与父组件中对应的状态变量建立双向数据绑定。

原文链接:https://juejin.cn/post/7448904415849365542
posted @ 2025-07-26 08:54  任淏  阅读(29)  评论(0)    收藏  举报