鸿蒙装饰器V1详解
PersistentStorage和AppStorage中的属性建立双向同步,UI和业务逻辑不直接访问PersistentStorage中的属性,所有属性的访问都是对AppStorage,AppStorage中的更改会自动同步到PersistentStorage。数组项中嵌套的属性赋值无法观察。对于嵌套场景的话,如果class被@Observed装饰,并且父组件给子组件传递的是该对象的嵌套对象时(
管理组件拥有的状态
-
1.
@State装饰器(组件内状态管理)
-
•
对象嵌套无法观察到变化,不会触发UI刷新。
-
•
装饰对象为Array时,可以观察到Array整体赋值及数组元素的赋值,同时可以调用Array的接口push、pop、shift、unshift、splice、copyWithin、fill、reverse、sort更新Array中的数据。数组项中嵌套的属性赋值无法观察。
-
•
装饰对象为Date时,可以观察到Date的赋值,以及通过调用Date接口的setFullYear、setMonth、setDate、setHours、setMinutes、setSeconds、setMilliseconds、setTime、setUTCFullYear、setUTCMonth、等更新Date属性。
-
•
装饰对象为Map时,可以观察到Map整体的赋值,以及通过调用Map的接口set、clear、delete更新Map的值。
-
•
装饰对象为Set时,可以观察到Set整体的赋值,以及通过调用Set的接口add、clear、delete更新Set的值。
-
•
会造成冗余刷新,当@State标记的某个属性变化,所有属性都会更新。
-
-
2.
@Prop装饰器(父子单向同步)
-
•
@Prop装饰的变量允许本地修改,但修改不会同步回父组件。
-
•
数据源更改时,@Prop装饰的变量都会更新,并且会覆盖本地所有更改。
-
•
组件复用场景,建议@Prop深度嵌套数据不要超过5层,嵌套太多会导致深拷贝占用的空间过大以及垃圾回收,引起性能问题,建议使用@ObjectLink。
-
•
装饰类型为Object时,可以观察到自身赋值以及第一层属性的变化。
-
•
对于嵌套场景的话,如果class被@Observed装饰,并且父组件给子组件传递的是该对象的嵌套对象时(在子组件中标记@Prop 嵌套对象),此时父组件直接使用对象.嵌套对象.属性修改时,子组件的UI会同步更改。
-
•
装饰类型为数组时,可以观察到数组本身的赋值和数组项的添加、删除和更新。
-
•
除了@State,数据源也可以用@Link和@Prop装饰,对@Prop的同步机制是相同的。
-
•
装饰类型为Map、Date、Set时,跟@State的情况一致。
-
-
3.
@Link装饰器(父子双向同步)
-
•
@Link仅能观察到对象本身及其一层属性的变化,无法观察嵌套场景内层数据的变化。
-
•
装饰对象为Array时,可以观察到数组添加、删除、更新数组单元的变化。
-
•
装饰对象为Date、Map、Set时跟@State类似,请参照。
-
•
@Link变量禁止本地初始化。
-
•
@Link变量类型要父子一致。
-
•
@Link变量只能被状态变量初始化。
-
-
4.
@Provide、@Consume装饰器(与后代组件双向同步)
-
•
@Provide装饰的变量在祖先组件中,被提供给后代的状态变量。@Cosume装饰的变量是在后代组件中,去消费祖先组件提供的变量。
-
•
@Provide指定变量别名时,会同时保存变量名与变量别名,@Consume在查找时,会优先以变量别名作为查找值去匹配,如果没有别名则用变量名作为查找值,只要@Consume提供的查找值与@Provide保存的变量名或别名中任意一项一致,即可成功建立绑定关系。
-
•
@Provide变量跟@Consume可以手动传入到子组件中,使用@Link、@Prop接收,并且会保留双向跟单向传递的能力。
-
•
@Consume在Api20以后支持设置默认值,匹配失败则使用默认值。
-
•
仅能观察到对象的赋值以及第一层属性的变化,
-
•
装饰对象为Array时,可以观察到数组添加、删除、更新数组单元的变化。
-
•
装饰对象为Date、Map、Set时跟@State类似,请参照。
-
•
@Provide装饰的变量会以map形式传递给当前@Provide所有组件的所有子组件。通过map匹配别名或者变量名查找。
-
•
key重复定义会引起运行时错误,可以使用allowoverride。
@Provide({ allowOverride: 'reviewVotes' }) reviewVotes: number = 10;
-
•
api20开始支持buildnode中使用。
-
-
5.
@Observed、@ObjectLink装饰器(嵌套类对象属性变化)
-
•
@ObjectLink和@Observed类装饰器配合使用,可实现嵌套对象或数组的双向数据同步。将类属性声明为@Observed装饰的类型,子组件中使用@ObjectLink装饰状态变量,接收父组件中@Observed装饰的类实例,从而建立双向绑定。
-
•
@ObjectLink的属性可以被改变,但不允许整体赋值,变量只读,否则执行到赋值代码会崩溃。
-
•
@Prop跟@Observed是单向,@ObjectLink跟@Observed是双向。
-
•
@ObjectLink接收的是父组件对象的嵌套对象实例。
-
•
api19前必须使用@Observed装饰,api19后可以通过makeV1Observed来观察嵌套类属性的变化,类似与@Observed。
@State outer: Outer = new Outer(UIUtils.makeV1Observed(new Inner()));
-
•
@ObjectLink推荐设计单独的自定义组件来渲染每一个数组或对象。此时,对象数组或嵌套对象需要定义两个自定义组件,一个自定义组件呈现外部数组或者对象,另一个自定义组件呈现嵌套在数组或对象内的类对象。
-
•
装饰对象为Date、Map、Set时跟@State类似,请参照。
-
•
@Observed装饰的class实例会被代理对象包装,代理了class的属性setter、getter方法。子组件的@ObjectLink装饰的包装类会将自己注册到@Observed类的依赖列表中,当@Observed装饰的class属性改变时,执行代理setter、getter,遍历@ObjectLink依赖列表通知数据更新。
-
•
@ObjectLink必须是负责类型,否则编译不通过。
-
-
6.
@Watch装饰器(状态变量更改通知)
-
•
@Watch用于监听状态变量的变化,当状态变量变化时,@Watch的回调方法被调用。内部判断数值有无更新使用严格相等===。
-
•
第一次初始化时,@Watch装饰的方法不会被调用,即认为初始化不是状态变量的改变。只有后续改变才会调用回调方法。
-
•
监听范围依赖状态变量能监听到的层级。
-
管理数据对象的状态
-
1.
@Track装饰器(class对象属性级更新)
-
•
@Track应用于class对象的属性级更新。当一个class对象是状态变量时,@Track装饰的属性变化时,只会触发该属性关联的UI更新。
-
•
如果class类中使用了@Track装饰器,则未被@Track装饰器装饰的属性不能在UI中使用,否则会发生运行时报错。
-
•
@Track不会造成冗余刷新,精准控制类属性进行更新具体值改变的UI。
-
管理应用拥有的状态
-
1.
LocalStorage:页面级UI状态(临时)存储
-
•
LocalStorage是ArkTS为构建页面级别状态变量提供存储的内存内的数据库,同页面及子组件内共享;生命周期随页面销毁释放。
-
•
组件树的根节点,可以被分配一个LocalStorage实例,此组件的所有子组件实例将自动获得对该LocalStorage实例的访问权限。@Component装饰的组件既可以自动继承来自父组件的LocalStorage实例,也可以传入指定的LocalStorage实例。
-
•
@LocalStorageProp:@LocalStorageProp装饰的变量与LocalStorage中给定属性建立单向同步关系。
-
•
@LocalStorageLink:@LocalStorageLink装饰的变量与LocalStorage中给定的属性建立双向同步关系。
-
-
2.
AppStorage:应用级全局状态(临时)存储
-
•
AppStorage是与应用进程绑定的全局UI状态存储中心,由UI框架在应用启动时创建的单例,将UI状态数据存储于运行内存,实现应用级全局状态共享。
-
•
作为应用的中枢,AppStorage是持久化数据PersistentStorage和环境变量Environment与UI交互中转桥梁。核心价值在于为开发者跨ability的大范围UI状态数据共享能力。
-
•
@StorageProp:与AppStorage中对应的属性建立单向数据同步。可以观察到class整体赋值以及属性的变化。其他参照@State。
-
•
@StorageLink与AppStorage中对应的属性建立双向数据同步。可以观察到class整体赋值以及属性的变化。其他参照@State。
-
•
状态装饰器的变量,改变会引起UI的渲染更新。如果改变的变量仅用于消息传递,不用于UI更新,推荐使用emitter方式。
-
•
不建议借助@StorageLink的双向同步机制实现事件通知,因为事件通知不一定需要通知到所有这些组件。
-
-
3.
PersistentStorage:持久化存储UI状态
-
•
PersistentStorage是应用程序中可选单例对象。此对象的作用是持久化存储选定的AppStorage属性,以确保这些属性在应用程序重新启动时的值与应用程序关闭时的值相同。PersistentStorage提供状态变量持久化的能力,其持久化和读回UI的能力都需要依赖AppStorage。
-
•
PersistentStorage将选定的AppStorage属性保留在设备磁盘上。应用程序通过API,以决定哪些属性应借助PersistentStorage持久化。PersistentStorage和AppStorage中的属性建立双向同步,UI和业务逻辑不直接访问PersistentStorage中的属性,所有属性的访问都是对AppStorage,AppStorage中的更改会自动同步到PersistentStorage。
-
•
PersistentStorage不允许的类型和值有:嵌套对象(对象数组,对象的属性是对象等)。目前无法检测AppStorage中嵌套对象值的变化,所以无法写回到PersistentStorage中。
-
•
PersistentStorage的持久化变量最好小于2kb的数据,不要大量的数据持久化,因为写入磁盘是在UI线程同步执行的,大量数据本地读写会影响UI渲染性能。
-
•
PersistentStorage和UI实例相关联,持久化操作需要再UI实例初始化成功后即loadContent成功回调后才可以被调用,早于这个时机调用会导致持久化失败。
-
•
PersistentStorage.persistProp(key, defaultValue)。如果PersistentStorage文件中存在key对应的属性,则取出属性赋值到AppStorage上;如果PersistentStorage文件没有查找key属性,则在AppStorage中查找key对应属性,找到则持久化;如果AppStorage中也没有找到则使用defaultValue初始化并持久化。
-
-
4.
Environment:设备环境查询
-
•
Environment是ArkUI框架在应用启动时创建的单例对象,为AppStorage提供应用程序运行状态的属性。所有属性都是不可变的简单类型。
-
•
类似于PersistentStorage。
-
更多推荐
所有评论(0)