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刷新

通过a.b(this.object)形式调用时,b方法内传入的是this.object的原生对象,修改其属性,无法触发UI刷新。如下例中,通过静态方法Score.changeScore1或者this.changeScore2修改Child组件中的this.score.value时,UI不会刷新。

注意:a.b(this.object)形式调用,在@Link、@Prop、@Observed、@ObjectLink@Provide、@Consume等装饰器中也是一样的࿰

### 更改 `@Prop` 注解为 `@ObjectLink` 的相关用法 当考虑将注解从 `@Prop` 替换为 `@ObjectLink` 时,主要关注的是两者之间的功能差异以及如何实现相同的目标。以下是详细的说明: #### 功能对比 - **`@Prop`**: 这种注解通常用于声明组件的输入属性,类似于 Vue.js 中的 props 或 React 中的 props 属性[^1]。 - **`@ObjectLink`**: 基于上下文推测,这种注解可能具有双向绑定的功能特性,允许父子组件之间共享状态并保持同步[^4]。 如果目标是从单向数据流切换到双向绑定,则需要调整代码逻辑以支持这一变化。 --- ### 实现方式 假设我们有一个场景,在该场景下原本通过 `@Prop` 定义的数据现在需要用 `@ObjectLink` 来替代。下面是一个具体的例子来展示转换过程。 #### 示例代码:原始版本(使用 `@Prop`) ```typescript import { Component } from 'some-framework'; @Component({ selector: 'child-component', }) export class ChildComponent { @Prop() data!: string; updateData(newData: string): void { console.log('Updated Data:', newData); } } ``` 在这个例子中,`data` 是由父组件传递给子组件的一个只读属性。 --- #### 转换后的版本(使用 `@ObjectLink`) 为了使 `@ObjectLink` 支持双向绑定,我们需要确保它不仅能够接收来自父组件状态,还能够在子组件内部对其进行修改并将更改反映回父组件。 ```typescript import { Component, ObjectLink } from 'some-framework'; @Component({ selector: 'child-component', }) export class ChildComponent { @ObjectLink() data!: string; // 双向绑定 updateData(newData: string): void { this.data = newData; // 修改会自动同步到父组件 console.log('Updated Data via ObjectLink:', newData); } } ``` 在此情况下,`@ObjectLink` 不仅接受初始值,还会监听任何对该变量所做的变更,并将其传播至关联的对象或组件实例。 --- ### 关键点分析 1. **元数据管理** 如果需要进一步扩展功能,比如附加额外的行为或者验证机制,可以通过反射 API 设置自定义元数据: ```typescript Reflect.defineMetadata('isEditable', true, ChildComponent.prototype, 'data'); const isEditable = Reflect.getMetadata('isEditable', ChildComponent.prototype, 'data'); ``` 2. **图像语法的支持** 对某些框架而言,注册自定义属性后可启用特定标记语言解析能力[^2]。例如: ```html <custom-element image="path/to/image.png"></custom-element> ``` 3. **依赖注入与自动化装配** 类似 Spring 框架中的依赖注入概念[^3],也可以引入类似的容器化解决方案简化复杂关系处理流程。不过这取决于具体技术栈的选择。 --- ### 总结 上述讨论展示了如何利用 `@ObjectLink` 替代传统意义上的 `@Prop` 注解完成更加灵活的任务需求。需要注意实际开发过程中应当仔细评估两者的适用范围及其潜在影响因素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值