HarmonyOS NEXT应用开发:ArkTS语言状态管理-@Prop装饰器:父子单向同步

 往期鸿蒙5.0全套实战文章必看:(文中附带全栈鸿蒙5.0学习资料)


@Prop装饰器:父子单向同步

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

说明:

从API version 9开始,该装饰器支持在ArkTS卡片中使用。

从API version 11开始,该装饰器支持在原子化服务中使用。

概述

@Prop装饰的变量和父组件建立单向的同步关系:

  • @Prop变量允许在本地修改,但修改后的变化不会同步回父组件。

  • 当数据源更改时,@Prop装饰的变量都会更新,并且会覆盖本地所有更改。因此,数值的同步是父组件到子组件(所属组件),子组件数值的变化不会同步到父组件。

限制条件

  • @Prop装饰变量时会进行深拷贝,在拷贝的过程中除了基本类型、Map、Set、Date、Array外,都会丢失类型。例如PixelMap等通过NAPI提供的复杂类型,由于有部分实现在Native侧,因此无法在ArkTS侧通过深拷贝获得完整的数据。

  • @Prop装饰器不能在@Entry装饰的自定义组件中使用。

装饰器使用规则说明

@Prop变量装饰器 说明
装饰器参数
同步类型 单向同步:对父组件状态变量值的修改,将同步给子组件@Prop装饰的变量,子组件@Prop变量的修改不会同步到父组件的状态变量上。
允许装饰的变量类型 Object、class、string、number、boolean、enum类型,以及这些类型的数组。
不支持任何,支持undefined和null。
支持Date类型。
API11及以上支持Map、Set类型。
支持ArkUI框架定义的联合类型Length、ResourceStr、ResourceColor类型。
必须指定类型。
@Prop和数据源类型需要相同,有以下三种情况:
- @Prop装饰的变量和@State以及其他装饰器同步时双方的类型必须相同。
- @Prop装饰的变量和@State以及其他装饰器装饰的数组的项同步时 ,@Prop的类型需要和@State装饰的数组项相同,比如@Prop : T和@State : Array<T>。
- 当父组件状态变量为Object或者class时,@Prop装饰的变量和父组件状态变量的属性类型相同。
支持类型的场景请参考观察变化
API11及以上支持上述支持类型的联合类型,比如string |数字, 字符串 |undefined 或者 ClassA |null。
注意
当使用undefined和null的时候,建议显式指定类型,遵循TypeScript类型校验,比如:是推荐的,不推荐。@Prop a : string | undefined = undefined@Prop a: string = undefined
嵌套传递层数 在组件复用场景,建议@Prop深度嵌套数据不要超过5层,嵌套太多会导致深拷贝占用的空间过大以及GarbageCollection(垃圾回收),引起性能问题,此时更建议使用@ObjectLink
被装饰变量的初始值 允许本地初始化。如果在API 11中和@Require结合使用,则必须父组件构造传参。

变量的传递/访问规则说明

传递/访问 说明
从父组件初始化 如果本地有初始化,则是可选的,初始化行为和@State保持一致。没有的话,则必选,支持父组件中的常规变量(常规变量对@Prop赋值,只是数值的初始化,常规变量的变化不会触发UI刷新。只有状态变量才能触发UI刷新)、@State@Link、@Prop、@Provide@Consume@ObjectLink@StorageLink@StorageProp@LocalStorageLink@LocalStorageProp去初始化子组件中的@Prop变量。
用于初始化子组件 @Prop支持去初始化子组件中的常规变量、@State、@Link、@Prop、@Provide。
是否支持组件外访问 @Prop装饰的变量是私有的,只能在组件内访问。

图1 初始化规则图示

zh-cn_image_0000001552972029

观察变化和行为表现

观察变化

@Prop装饰的数据可以观察到以下变化。

  • 当装饰的类型是允许的类型,即Object、class、string、number、boolean、enum类型都可以观察到赋值的变化。

    <span style="background-color:#f6f8fa"><span style="color:#000000"><code><img data-cke-saved-src="https://docs.openharmony.cn/copy.png" src="https://docs.openharmony.cn/copy.png" alt="" width="20" height="20" class="copy-img" /><span style="color:green">// 简单类型</span>
    <span style="color:green">@Prop</span> count: <span style="color:green">number</span>;
    <span style="color:green">// 赋值的变化可以被观察到</span>
    <span style="color:#0055af">this</span>.count = <span style="color:navy">1</span>;
    <span style="color:green">// 复杂类型</span>
    <span style="color:green">@Prop</span> title: <span style="color:#0055af">Model</span>;
    <span style="color:green">// 可以观察到赋值的变化</span>
    <span style="color:#0055af">this</span>.title = <span style="color:olive">new</span> <span style="color:#0055af">Model</span>(<span style="color:green">'Hi'</span>);
    <strong>ts</strong></code></span></span>
  • 当装饰的类型是Object或者class复杂类型时,可以观察到第一层的属性的变化,属性即Object.keys(observedObject)返回的所有属性;

<span style="background-color:#f6f8fa"><span style="color:#000000"><code><img data-cke-saved-src="https://docs.openharmony.cn/copy.png" src="https://docs.openharmony.cn/copy.png" alt="" width="20" height="20" class="copy-img" /><span style="color:olive">class</span> <span style="color:#0055af">Info</span> {
  <span style="color:olive">public</span> value: <span style="color:green">string</span>;
  <span style="color:#000000">constructor</span>(<span style="color:#0055af">value: <span style="color:green">string</span></span>) {
    <span style="color:#0055af">this</span>.value = value;
  }
}
<span style="color:olive">class</span> <span style="color:#0055af">Model</span> {
  <span style="color:olive">public</span> value: <span style="color:green">string</span>;
  <span style="color:olive">public</span> info: <span style="color:#0055af">Info</span>;
  <span style="color:#000000">constructor</span>(<span style="color:#0055af">value: <span style="color:green">string</span>, info: Info</span>) {
    <span style="color:#0055af">this</span>.value = value;
    <span style="color:#0055af">this</span>.info = info;
  }
}

<span style="color:green">@Prop</span> title: <span style="color:#0055af">Model</span>;
<span style="color:green">// 可以观察到第一层的变化</span>
<span style="color:#0055af">this</span>.title.value = <span style="color:green">'Hi'</span>;
<span style="color:green">// 观察不到第二层的变化</span>
<span style="color:#0055af">this</span>.title.info.value = <span style="color:green">'ArkUI'</span>;
<strong>ts</strong></code></span></span>

对于嵌套场景,如果class是被@Observed装饰的,可以观察到class属性的变化。

  • 当装饰的类型是数组的时候,可以观察到数组本身的赋值和数组项的添加、删除和更新。
<span style="background-color:#f6f8fa"><span style="color:#000000"><code><img data-cke-saved-src="https://docs.openharmony.cn/copy.png" src="https://docs.openharmony.cn/copy.png" alt="" width="20" height="20" class="copy-img" /><span style="color:green">// @State装饰的对象为数组时</span>
<span style="color:green">@Prop</span> title: <span style="color:green">string</span>[];
<span style="color:green">// 数组自身的赋值可以观察到</span>
<span style="color:#0055af">this</span>.title = [<span style="color:green">'1'</span>];
<span style="color:green">// 数组项的赋值可以观察到</span>
<span style="color:#0055af">this</span>.title[<span style="color:navy">0</span>] = <span style="color:green">'2'</span>;
<span style="color:green">// 删除数组项可以观察到</span>
<span style="color:#0055af">this</span>.title.<span style="color:#000000">pop</span>();
<span style="color:green">// 新增数组项可以观察到</span>
<span style="color:#0055af">this</span>.title.<span style="color:#000000">push</span>(<span style="color:green">'3'</span>);
<strong>ts</strong></code></span></span>

对于@State和@Prop的同步场景:

  • 使用父组件中@State变量的值初始化子组件中的@Prop变量。当@State变量变化时,该变量值也会同步更新至@Prop变量。

  • @Prop装饰的变量的修改不会影响其数据源@State装饰变量的值。

  • 除了@

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值