ArkTS状态管理装饰器V1版本(@State、@Prop、@Link、@ObjectLink、@Provide、@Consume、@StorageProp、@StorageLink等)

目录

ArkTS状态管理装饰器V1

组件定义

@Component

freezeWhenInactive11+

@Entry(通用)

EntryOptions10+

Component、Entry示例

@Reusable

组件状态管理

@State

a.b(this.object)形式调用,不会触发UI刷新

@Prop

State、Prop、Link示例

@Provide、@Consume

aliasName

重写@Provide

Provide、Consume示例

Observed、ObjectLink示例

页面状态存储

@LocalStorageProp

@LocalStorageLink

示例

自定义组件接收LocalStorage

其它状态管理

$$

$$示例

@Watch

Watch示例

@Track

Track示例


ArkTS状态管理装饰器V1

arkts早期提供给开发者使用的状态管理装饰器,对于嵌套类的观测存在诸多限制。在API12中为开发者提供了一套全新的状态管理V2(简称V2)。官方是希望后续用V2版本的装饰器取代V1的装饰器。实际上目前大部分的开发代码仍使用的是V1版本的装饰器。

装饰器类别 装饰器
组件内装饰器 @State、@Prop、@Link、@ObjectLink、@Provide、@Consume、@StorageProp、@StorageLink、@LocalStorageProp、@LocalStorageLink、@Watch
类相关装饰器 @Observed、@Track

组件定义

@Component

@Component装饰器仅能装饰struct关键字声明的数据结构。struct被@Component装饰后具备组件化的能力,需要实现build方法描述UI,一个struct只能被一个@Component装饰。@Component可以接受一个可选的bool类型参数,用来冻结自定义组件(冻结的组件不会随@state变量更新变化UI)。

freezeWhenInactive11+

组件冻结选项。

名称 类型 必填 说明
freezeWhenInactive bool 是否开启组件冻结。
@Component({ freezeWhenInactive: true })
struct MyComponent {
}

@Entry(通用)

修饰@Component定义的自定义组件,将其作为入口组件。

入口组件:可以作为页面路由单独显示的,可以理解为一个完整的页面,无@Entry修饰的自定义组件只是部分页面,应用只能显示完整的页面,可以通过windowStage.loadContent方法决定挂载哪一个完整页面。

@Entry可以接受一个可选的LocalStorage的参数或者一个可选的EntryOptions参数。入参见

EntryOptions10+

命名路由跳转选项。

名称 类型 必填 说明
routeName string 表示作为命名路由页面的名字。
storage LocalStorage 页面级的UI状态存储。
useSharedStorage12+ boolean 是否使用LocalStorage.getShared()接口返回的LocalStorage实例对象,默认值false。

说明

当useSharedStorage设置为true,并且storage也被赋值时,useSharedStorage的值优先级更高

@Entry({ routeName : 'myPage' })
@Component
struct MyComponent {
}

Component、Entry示例

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  build() {
    RelativeContainer() {
      Text(this.message)
        .id('HelloWorld')
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
    }
    .height('100%')
    .width('100%')
  }
}

@Reusable

@Reusable适用自定义组件,与@Component结合使用,标记为@Reusable的自定义组件从组件树上被移除时,组件和其对应的JSView对象都会被放入复用缓存中,后续创建新自定义组件节点时,会复用缓存区中的节点,节约组件重新创建的时间。

复用组件的时候会执行aboutToReuse方法,该方法接收一个参数,参数上挂载了自定义组件被删除前的状态变量。

文档中心

组件状态管理

通过代理监听被装饰变量的变化来刷新组件的UI。

@State、@Prop、@Link装饰的变量可以监视基础变量的变化,以及复杂类型变量的单层变化,例如装饰对象时,可以监听到第一层属性指向的值的变化。当有嵌套时,是无法监听到里层属性的变化。

文档中心

@State

修饰自定义组件中的属性变量,变量变化会触发自定义组件的UI刷新。修饰的变量需要初始值

父组件调用自定义组件时可以通过同名入参传入子组件@State修饰的属性变量的值(会覆盖子组件中定义的初始值),但是父组件中的传入值变化不会导致子组件中的变量变化。如果想实现父到子的同步可以使用@Prop,想实现父子的完全同步可以使用@Link。

a.b(this.object)形式调用,不会触发UI刷新

<think>我们开始鸿蒙工程师职位的面试。我会认真回答每一个问题,并按照要求以纯文字口述表达。 注意:回答完问题后,必须根据用户的问题及我的回答提出3-5个相关问题,并以“§§相关问题§§”开头,然后列出问题。 首先,回答第一个问题:model的使用场景,模块。 回答:在鸿蒙开发中,Model是ArkUI框架中用于管理应用状态的一种机制。它主要用于将应用的数据和业务逻辑与UI分离,实现数据驱动视图更新。Model的使用场景包括: 1. 管理应用级的状态:当多个页面需要共享同一份数据时,可以将这些数据放在Model中,实现跨页面的状态共享。 2. 管理页面级的状态:在单个页面内,Model可以管理该页面的状态,使得状态变更可以自动更新UI。 3. 管理组件级的状态:对于组件内部的状态,也可以使用Model来管理,但通常更推荐使用组件内部的状态装饰器(如@State)。 Model模块通常指的是在鸿蒙应用中创建的模型类,这些类使用装饰器(如@Observed、@Prop@Link等)来装饰属性,以实现状态管理。在ArkUI中,Model模块通常通过创建类并配合装饰器来实现。 接下来,回答第二个问题:hap,hsp,har之间的关系。 回答: - HAP(HarmonyOS Ability Package):是鸿蒙应用的安装包,包含一个或多个Ability(如Page Ability、Service Ability等)以及资源文件、库文件等。HAP可以直接安装到设备上运行。 - HSP(HarmonyOS Shared Package):是动态共享包,它包含一些共享的代码、资源和so库。HSP不能独立安装,需要被其他HAP依赖。多个HAP可以共享同一个HSP,从而减少应用体积。 - HAR(HarmonyOS Ability Resources):是静态共享包,它包含代码和资源,在编译时会被打包到依赖它的HAP中。与HSP不同,HAR在编译时就被静态地打包到HAP中,因此每个HAP都包含一份HAR的副本。 它们之间的关系:HAR和HSP都是为了实现代码和资源的共享,但HAR是静态共享,而HSP是动态共享。HAP是应用的安装包,它可以依赖HAR或HSP。 第三个问题:har,直接在里面做混淆。 回答:在HAR(静态共享包)中,我们可以对代码进行混淆。混淆的目的是为了保护代码,防止反编译。在鸿蒙开发中,我们可以使用ProGuard等工具对HAR中的代码进行混淆。需要注意的是,混淆配置需要正确设置,以避免混淆掉不该混淆的类或方法(例如,被反射调用的类、与JS交互的类等)。混淆通常在编译阶段进行,配置在项目的build.gradle文件中。 第四个问题:鸿蒙开发中有哪几种生命周期?组件的,应用的。 回答: 1. 应用生命周期:包括应用创建、应用前台可见、应用后台运行、应用销毁等阶段。具体回调方法有onCreate、onDestroy等。 2. 组件生命周期:对于UI组件(如Ability),有自己特定的生命周期。例如: - Page Ability的生命周期:onInit、onReady、onShow、onHide、onDestroy等。 - Service Ability的生命周期:onStart、onCommand、onConnect、onDisconnect、onStop等。 3. UI组件(如自定义组件)也有自己的生命周期,例如aboutToAppear、aboutToDisappear等。 第五个问题:uiability的生命周期顺序。 回答:UIAbility(用户界面能力)是鸿蒙系统中提供的一个Ability,用于与用户交互。其生命周期顺序如下: 1. onCreate:当Ability被创建时调用,用于初始化操作。 2. onWindowStageCreate:当Ability的窗口被创建时调用,可以在此设置UI页面。 3. onForeground:当Ability从后台切换到前台时调用。 4. onBackground:当Ability从前台切换到后台时调用。 5. onWindowStageDestroy:当Ability的窗口被销毁时调用。 6. onDestroy:当Ability被销毁时调用。 第六个问题:ui状态管理,v1,v2。 回答:鸿蒙的UI状态管理有两个版本:V1和V2。 - V1:基于JavaScript的声明式UI框架,使用@State@Prop@Link装饰器管理状态。 - V2:基于TypeScript的声明式UI框架(即ArkUI),使用更简洁的语法,并且性能更好。V2中状态管理装饰器与V1类似,但做了一些优化和增强。 第七个问题:管理组件拥有的状态有哪些装饰器。 回答:管理组件拥有的状态装饰器包括: - @State组件内部的状态,当状态变化时,会重新渲染组件。 - @Prop:从父组件传递到子组件状态,子组件内部可以修改,但不会影响父组件(单向绑定)。 - @Link:与父组件建立双向绑定,子组件修改该状态会同步到父组件。 - @Provide@Consume:用于跨组件层级的状态传递,祖先组件提供状态@Provide),后代组件消费状态@Consume),也是双向绑定。 - @ObjectLink:用于与嵌套对象或数组中的属性建立双向绑定,通常与@Observed装饰器一起使用。 第八个问题:prop和link的区别,修饰什么类型数据? 回答: - @Prop:是单向绑定,只能从父组件传递到子组件,子组件内部可以修改该值,但不会回传给父组件。它修饰的数据类型可以是基本类型(number, string, boolean等)或复杂对象(但需要是@Observed装饰的类实例)。 - @Link:是双向绑定,父组件和子组件共享同一个状态,子组件的修改会同步到父组件。它修饰的数据类型必须是引用类型(如对象、数组),且通常需要是@Observed装饰的类实例。 第九个问题:深层,嵌套多层要用什么装饰器。 回答:对于深层嵌套的对象,我们使用@Observed装饰器来装饰类,然后在组件中使用@ObjectLink装饰器来建立双向绑定。这样,当嵌套对象的属性发生变化时,UI能够自动更新。 第十个问题:monitor具体是怎么监测的。 回答:在鸿蒙开发中,@Monitor装饰器(实际上在文档中通常称为@Watch)用于监听状态变量的变化。当被监视的状态变量发生变化时,会触发指定的回调函数。例如: ```typescript @State @Watch('onCountChange') count: number = 0; onCountChange() { // 当count变化时执行 } ``` 监测机制是通过在状态变量被修改时,检查该变量是否被@Watch装饰,如果是,则调用对应的回调函数。 第十一个问题:@observed要搭配什么装饰器(@)? 回答:@Observed装饰器通常需要搭配@ObjectLink@Prop装饰器使用。@Observed用于装饰类,表示这个类的实例可以被观察,而@ObjectLink@Prop用于在组件中引用该类的实例,以实现对嵌套对象属性的监听。 第十二个问题:管理应用拥有的状态有哪些装饰器,为什么能共享数据?讲一下原理。 回答:管理应用拥有的状态装饰器@StorageLink@StorageProp、LocalStorage等。它们能够共享数据的原理是:通过LocalStorage这个存储空间,将状态保存在应用级别,然后通过装饰器状态与UI组件绑定。当状态变化时,所有绑定该状态组件都会更新。 - @StorageLink:双向绑定,组件修改状态会同步到LocalStorage,其他绑定的组件也会更新。 - @StorageProp:单向绑定,组件不能直接修改LocalStorage中的状态,只能通过LocalStorage的API修改。 原理:LocalStorage是一个应用级的存储,在应用启动时创建,并可以在整个应用的UI组件中访问。装饰器@StorageLink@StorageProp会将UI组件中的变量与LocalStorage中的属性建立连接,当LocalStorage中的属性变化时,会通知所有连接的组件更新。 第十三个问题:persistentStorage可以写在什么地方才能生效?(页面级) 回答:PersistentStorage(持久化存储)用于将应用状态持久化到设备上(如存储到本地文件)。它通常需要在应用启动时初始化,因此建议在EntryAbility的onCreate方法中调用PersistentStorage.persistProp方法来设置需要持久化的属性。这样,当应用启动时,就会从持久化存储中读取数据,并在应用退出时将数据写入存储。 第十四个问题:监听器,@watch怎么应用的?场景 回答:@Watch装饰器用于监听状态变量的变化。使用方式是在状态变量上添加@Watch装饰器,并指定一个回调函数。当状态变量发生变化时,回调函数会被调用。应用场景: - 当状态变化时需要执行一些逻辑(如发送网络请求、更新其他状态等)。 - 表单验证:当输入框的值变化时,进行实时验证。 第十五个问题:v1的$$和V2 !!有什么区别 回答: - V1中的$$:用于在JS组件中访问系统变量,如$$.app代表应用对象,$$.context代表上下文。 - V2中的!!:在ArkUI(V2)中,!!用于将非布尔类型转换为布尔类型,通常用于条件渲染中。例如,`if (!!this.count)`将count转换为布尔值。 第十六个问题:$$支持的组件,在你开发当中有哪些引用到的 回答:在V1中,$$支持在JS组件中使用,可以访问到一些系统对象。例如: - $$.app:应用对象 - $$.context:上下文对象 - $$.page:页面对象 在开发中,我使用$$.context来获取资源路径、应用文件路径等。 第十七个问题:音视频开发有一个必要的组件?Xcomponet,是干嘛的?有一个属性设置,type,这个属性里面可以传什么值,surface,texture 回答:XComponent是鸿蒙中用于多媒体开发(如视频、相机、OpenGL渲染)的组件。它提供了一个绘制表面(Surface),用于显示视频帧或进行图形绘制。 - type属性:指定XComponent的类型,可以传入以下值: - "surface":用于显示视频或相机预览,此时XComponent会提供一个Surface对象,可以将该Surface对象传递给媒体服务(如播放器)来渲染视频。 - "texture":用于OpenGL纹理绘制,通常用于自定义图形渲染(如游戏、3D图形)。 第十八个问题:foreach,lazyforeach有什么区别?关键的一个key,如果有相同的情况下,key有什么作用 回答: - ForEach:用于循环渲染数组中的每个元素,它会立即渲染所有元素。需要为每个元素指定一个唯一的key,用于标识该元素。当数组变化时,ForEach会根据key来判断元素是新增、删除还是移动,从而高效更新UI。 - LazyForEach:用于懒加载,它不会一次性渲染所有元素,而是只渲染可视区域内的元素,当滚动时再渲染其他元素。同样需要指定key,作用与ForEach相同。 当key相同时,ForEach和LazyForEach会认为它们是同一个元素,因此在数组变化时可能会导致错误的更新(例如,两个元素有相同的key,那么框架会认为它们是同一个元素,从而复用组件,可能导致显示错误)。所以,必须确保key的唯一性。 现在,根据以上问题和回答,提出3-5个相关问题: §§相关问题§§ 1. 在鸿蒙应用开发中,如何选择使用HAR还是HSP来实现代码共享? 2. 请解释在UIAbility的生命周期方法onWindowStageCreate中通常需要做哪些操作? 3. 在使用@ObjectLink和@Observed进行深层嵌套对象的状态管理时,需要注意哪些问题? 4. 请举例说明@Watch装饰器在表单验证场景中的具体应用。 5. 在使用XComponent进行视频播放时,如何将XComponent的Surface与媒体播放器关联起来?</think>### 鸿蒙工程师面试回答 #### 1. **model的使用场景,模块** Model在鸿蒙中用于数据管理,主要场景包括: - **状态共享**:跨组件/页面共享数据(如用户信息)。 - **逻辑解耦**:分离UI与业务逻辑,提升可维护性。 - **模块化**:通过`@Observed`装饰的Model类封装数据,结合`@ObjectLink`实现深层状态同步。 #### 2. **hap,hsp,har之间的关系** - **HAP**(HarmonyOS Ability Package):应用安装包,包含可运行的Ability和资源。 - **HSP**(HarmonyOS Shared Package):动态共享包,多个HAP可共享其代码/资源(运行时加载)。 - **HAR**(HarmonyOS Ability Resources):静态共享包,代码/资源在编译时拷贝到依赖的HAP中。 **关系**:HAP依赖HSP或HAR实现复用;HSP节省存储空间,HAR简化编译。 #### 3. **har,直接在里面做混淆** 在HAR中可通过ProGuard进行代码混淆: - 配置`build-profile.json5`,启用`minifyEnabled`。 - 规则文件保留`@Entry`、`@Component`等装饰的类,避免混淆后UI绑定失效。 - **生效条件**:依赖HAR的HAP需同步启用混淆。 #### 4. **鸿蒙开发中有哪几种生命周期?组件的,应用的** - **应用生命周期**(在`AppAbility`中): `onCreate` → `onRequest` → `onDestroy`。 - **组件生命周期**(UI组件): `aboutToAppear`(创建)→ `onPageShow`(显示)→ `onPageHide`(隐藏)→ `aboutToDisappear`(销毁)。 - **Ability生命周期**: `onCreate` → `onWindowStageCreate` → `onForeground` → `onBackground` → `onWindowStageDestroy` → `onDestroy`。 #### 5. **UIAbility的生命周期顺序** 完整顺序: 1. `onCreate`(Ability初始化) 2. `onWindowStageCreate`(窗口创建,加载UI) 3. `onForeground`(切换到前台) 4. `onBackground`(切换到后台) 5. `onWindowStageDestroy`(窗口销毁) 6. `onDestroy`(Ability销毁)。 #### 6. **UI状态管理,v1,v2** - **V1**:基于JS的类Web开发范式,使用`this.data`和`$$`语法管理状态。 - **V2**(推荐):基于ArkTS的声明式UI,使用装饰器(如`@State`)实现响应式更新,性能更优。 #### 7. **管理组件拥有的状态有哪些装饰器** - `@State`:组件私有状态。 - `@Prop`:父组件单向传递状态。 - `@Link`:父组件双向绑定的状态。 - `@Provide`/`@Consume`:跨组件层级双向绑定。 - `@ObjectLink`:嵌套对象的属性绑定(需配合`@Observed`)。 #### 8. **Prop和Link的区别,修饰什么类型数据?** - **区别**: - `@Prop`:**单向同步**,子组件修改不传回父组件。 - `@Link`:**双向同步**,父子组件状态实时同步。 - **数据类型**: - `@Prop`:基本类型(string/number)或简单对象。 - `@Link`:引用类型(对象、数组),需用`@Observed`装饰的类。 #### 9. **深层,嵌套多层要用什么装饰器** 使用`@Observed` + `@ObjectLink`: - `@Observed`装饰嵌套对象的类(如`class NestedData`)。 - 子组件用`@ObjectLink`绑定对象属性,实现深层属性变更监测。 #### 10. **Monitor具体是怎么监测的** `@Watch`装饰器实现监测: - 语法:`@State @Watch('回调函数') count: number = 0`。 - **原理**:状态变更时触发回调,如: ```typescript @State @Watch('onCountChange') count: number = 0; onCountChange() { console.log('Count changed!'); } ``` #### 11. **@Observed要搭配什么装饰器** 必须搭配`@ObjectLink`: - `@Observed`标记类(如`@Observed class User`)。 - 子组件用`@ObjectLink user: User`绑定属性,实现嵌套对象更新。 #### 12. **管理应用拥有的状态有哪些装饰器,为什么能共享数据?原理** - **装饰器**:`@StorageLink`、`@StorageProp`(基于`LocalStorage`)。 - **共享原理**: - `LocalStorage`是应用级内存,存储全局状态。 - 装饰器组件变量与`LocalStorage`的key绑定,数据变更时通过发布-订阅模式通知所有绑定组件更新。 #### 13. **PersistentStorage可以写在什么地方才能生效?** 需在**页面加载前初始化**: - 在`EntryAbility`的`onCreate`中调用: ```typescript PersistentStorage.PersistProp('key', 'defaultValue'); ``` - 之后在UI中通过`@StorageLink`使用,数据会自动持久化到设备。 #### 14. **监听器@Watch怎么应用的?场景** - **应用**:装饰状态变量并指定回调函数: ```typescript @State @Watch('validateEmail') email: string = ''; validateEmail() { /* 校验逻辑 */ } ``` - **场景**:表单输入校验、状态变更日志、联动更新其他状态。 #### 15. **V1的$$和V2 !!有什么区别** - **V1的$$**:用于访问系统能力(如`$$.context`获取上下文)。 - **V2的!!**:类型转换符,将非布尔值转为布尔(如`if (!!value)`)。 **本质区别**:`$$`是全局对象,`!!`是TS/JS语法特性。 #### 16. **$$支持的组件,开发中有哪些引用到的** - **支持组件**:所有V1的JS组件。 - **常用引用**: - `$$.app`:应用信息。 - `$$.context`:资源路径(如`this.context.resourceDir`)。 - `$$.element`:DOM操作(V2已弃用)。 #### 17. **音视频开发必要的组件?XComponent,作用?type属性传值** - **XComponent**:用于音视频/图形渲染的容器组件。 - **作用**:提供`Surface`作为播放器/相机的渲染载体。 - **type属性**: - `'surface'`:视频/相机预览(输出`Surface`对象)。 - `'texture'`:OpenGL纹理渲染(如游戏画面)。 #### 18. **ForEach,LazyForEach区别?key的作用** - **区别**: - `ForEach`:立即渲染全部数据,适合短列表。 - `LazyForEach`:懒加载(滚动时渲染),适合长列表优化性能。 - **key的作用**: - 唯一标识元素,复用组件(如`item.id`)。 - **重复key的后果**:渲染错乱、性能下降(框架无法正确复用节点)。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值