整站seo优化一般多少钱,网站建设实训小组报告,wordpress打开速度优化,建设工程施工合同范本哪个网站Provide和Consume#xff0c;应用于与后代组件的双向数据同步#xff0c;应用于状态数据在多个层级之间传递的场景。不同于上文提到的父子组件之间通过命名参数机制传递#xff0c;Provide和Consume摆脱参数传递机制的束缚#xff0c;实现跨层级传递。
其中Provide装饰的变…Provide和Consume应用于与后代组件的双向数据同步应用于状态数据在多个层级之间传递的场景。不同于上文提到的父子组件之间通过命名参数机制传递Provide和Consume摆脱参数传递机制的束缚实现跨层级传递。
其中Provide装饰的变量是在祖先组件中可以理解为被“提供”给后代的状态变量。Consume装饰的变量是在后代组件中去“消费绑定”祖先组件提供的变量。 说明 从API version 9开始这两个装饰器支持在ArkTS卡片中使用。 概述
Provide/Consume装饰的状态变量有以下特性 Provide装饰的状态变量自动对其所有后代组件可用即该变量被“provide”给他的后代组件。由此可见Provide的方便之处在于开发者不需要多次在组件之间传递变量。 后代通过使用Consume去获取Provide提供的变量建立在Provide和Consume之间的双向数据同步与State/Link不同的是前者可以在多层级的父子组件之间传递。 Provide和Consume可以通过相同的变量名或者相同的变量别名绑定建议类型相同否则会发生类型隐式转换从而导致应用行为异常。
// 通过相同的变量名绑定
Provide a: number 0;
Consume a: number;// 通过相同的变量别名绑定
Provide(a) b: number 0;
Consume(a) c: number;
Provide和Consume通过相同的变量名或者相同的变量别名绑定时Provide装饰的变量和Consume装饰的变量是一对多的关系。不允许在同一个自定义组件内包括其子组件中声明多个同名或者同别名的Provide装饰的变量Provide的属性名或别名需要唯一且确定如果声明多个同名或者同别名的Provide装饰的变量会发生运行时报错。
装饰器说明
State的规则同样适用于Provide差异为Provide还作为多层后代的同步源。
Provide变量装饰器说明装饰器参数别名常量字符串可选。 如果指定了别名则通过别名来绑定变量如果未指定别名则通过变量名绑定变量。同步类型双向同步。 从Provide变量到所有Consume变量以及相反的方向的数据同步。双向同步的操作与State和Link的组合相同。允许装饰的变量类型Object、class、string、number、boolean、enum类型以及这些类型的数组。 支持Date类型。 API11及以上支持Map、Set类型。 支持类型的场景请参考观察变化。 API11及以上支持上述支持类型的联合类型比如string | number, string | undefined 或者 ClassA | null示例见Provide_and_Consume支持联合类型实例。注意 当使用undefined和null的时候建议显式指定类型遵循TypeScript类型校验比如Provide a : string | undefined undefined是推荐的不推荐Provide a: string undefined。 支持ArkUI框架定义的联合类型Length、ResourceStr、ResourceColor类型。 不支持any。必须指定类型。 Provide变量的Consume变量的类型必须相同。被装饰变量的初始值必须指定。支持allowOverride参数允许重写只要声明了allowOverride则别名和属性名都可以被Override。示例见Provide支持allowOverride参数。
Consume变量装饰器说明装饰器参数别名常量字符串可选。 如果提供了别名则必须有Provide的变量和其有相同的别名才可以匹配成功否则则需要变量名相同才能匹配成功。同步类型双向从Provide变量具体请参见Provide到所有Consume变量以及相反的方向。双向同步操作与State和Link的组合相同。允许装饰的变量类型Object、class、string、number、boolean、enum类型以及这些类型的数组。 支持Date类型。 支持类型的场景请参考观察变化。 API11及以上支持上述支持类型的联合类型比如string | number, string | undefined 或者 ClassA | null示例见Provide_and_Consume支持联合类型实例。注意 当使用undefined和null的时候建议显式指定类型遵循TypeScript类型校验比如Consume a : string | undefined。 支持ArkUI框架定义的联合类型Length、ResourceStr、ResourceColor类型。 不支持any。必须指定类型。 Provide变量和Consume变量的类型必须相同。 Consume装饰的变量在其父组件或者祖先组件上必须有对应的属性和别名的Provide装饰的变量。被装饰变量的初始值无禁止本地初始化。
变量的传递/访问规则说明
Provide传递/访问说明从父组件初始化和更新可选允许父组件中常规变量常规变量对Prop赋值只是数值的初始化常规变量的变化不会触发UI刷新只有状态变量才能触发UI刷新、State、Link、Prop、Provide、Consume、ObjectLink、StorageLink、StorageProp、LocalStorageLink和LocalStorageProp装饰的变量装饰变量初始化子组件Provide。用于初始化子组件允许可用于初始化State、Link、Prop、Provide。和父组件同步否。和后代组件同步和Consume双向同步。是否支持组件外访问私有仅可以在所属组件内访问。
图1 Provide初始化规则图示 Consume传递/访问说明从父组件初始化和更新禁止。通过相同的变量名和alias别名从Provide初始化。用于初始化子组件允许可用于初始化State、Link、Prop、Provide。和祖先组件同步和Provide双向同步。是否支持组件外访问私有仅可以在所属组件内访问
图2 Consume初始化规则图示 观察变化和行为表现
观察变化 当装饰的数据类型为boolean、string、number类型时可以观察到数值的变化。 当装饰的数据类型为class或者Object的时候可以观察到赋值和属性赋值的变化属性为Object.keys(observedObject)返回的所有属性。 当装饰的对象是array的时候可以观察到数组的添加、删除、更新数组单元。 当装饰的对象是Date时可以观察到Date整体的赋值同时可通过调用Date的接口setFullYear, setMonth, setDate, setHours, setMinutes, setSeconds, setMilliseconds, setTime, setUTCFullYear, setUTCMonth, setUTCDate, setUTCHours, setUTCMinutes, setUTCSeconds, setUTCMilliseconds 更新Date的属性。
Component
struct CompD {Consume selectedDate: Date;build() {Column() {Button(child increase the day by 1).onClick(() {this.selectedDate.setDate(this.selectedDate.getDate() 1)})Button(child update the new date).margin(10).onClick(() {this.selectedDate new Date(2023-09-09)})DatePicker({start: new Date(1970-1-1),end: new Date(2100-1-1),selected: this.selectedDate})}}
}Entry
Component
struct CompA {Provide selectedDate: Date new Date(2021-08-08)build() {Column() {Button(parent increase the day by 1).margin(10).onClick(() {this.selectedDate.setDate(this.selectedDate.getDate() 1)})Button(parent update the new date).margin(10).onClick(() {this.selectedDate new Date(2023-07-07)})DatePicker({start: new Date(1970-1-1),end: new Date(2100-1-1),selected: this.selectedDate})CompD()}}
} 当装饰的变量是Map时可以观察到Map整体的赋值同时可通过调用Map的接口set, clear, delete 更新Map的值。详见装饰Map类型变量。 当装饰的变量是Set时可以观察到Set整体的赋值同时可通过调用Set的接口add, clear, delete 更新Set的值。详见装饰Set类型变量。
框架行为 初始渲染 Provide装饰的变量会以map的形式传递给当前Provide所属组件的所有子组件子组件中如果使用Consume变量则会在map中查找是否有该变量名/alias别名对应的Provide的变量如果查找不到框架会抛出JS ERROR在初始化Consume变量时和State/Link的流程类似Consume变量会保存在map中查找到的Provide变量并把自己注册给Provide。 当Provide装饰的数据变化时 通过初始渲染的步骤可知子组件Consume已把自己注册给父组件。父组件Provide变量变更后会遍历更新所有依赖它的系统组件elementid和状态变量Consume通知Consume更新后子组件所有依赖Consume的系统组件elementId都会被通知更新。以此实现Provide对Consume状态数据同步。 当Consume装饰的数据变化时 通过初始渲染的步骤可知子组件Consume持有Provide的实例。在Consume更新后调用Provide的更新方法将更新的数值同步回Provide以此实现Consume向Provide的同步更新。
使用场景
在下面的示例是与后代组件双向同步状态Provide和Consume场景。当分别点击CompA和CompD组件内Button时reviewVotes 的更改会双向同步在CompA和CompD中。
Component
struct CompD {// Consume装饰的变量通过相同的属性名绑定其祖先组件CompA内的Provide装饰的变量Consume reviewVotes: number;build() {Column() {Text(reviewVotes(${this.reviewVotes}))Button(reviewVotes(${this.reviewVotes}), give 1).onClick(() this.reviewVotes 1)}.width(50%)}
}Component
struct CompC {build() {Row({ space: 5 }) {CompD()CompD()}}
}Component
struct CompB {build() {CompC()}
}Entry
Component
struct CompA {// Provide装饰的变量reviewVotes由入口组件CompA提供其后代组件Provide reviewVotes: number 0;build() {Column() {Button(reviewVotes(${this.reviewVotes}), give 1).onClick(() this.reviewVotes 1)CompB()}}
}
装饰Map类型变量 说明 从API version 11开始ProvideConsume支持Map类型。 在下面的示例中message类型为Mapnumber, string点击Button改变message的值视图会随之刷新。
Component
struct Child {Consume message: Mapnumber, stringbuild() {Column() {ForEach(Array.from(this.message.entries()), (item: [number, string]) {Text(${item[0]}).fontSize(30)Text(${item[1]}).fontSize(30)Divider()})Button(Consume init map).onClick(() {this.message new Map([[0, a], [1, b], [3, c]])})Button(Consume set new one).onClick(() {this.message.set(4, d)})Button(Consume clear).onClick(() {this.message.clear()})Button(Consume replace the first item).onClick(() {this.message.set(0, aa)})Button(Consume delete the first item).onClick(() {this.message.delete(0)})}}
}Entry
Component
struct MapSample {Provide message: Mapnumber, string new Map([[0, a], [1, b], [3, c]])build() {Row() {Column() {Button(Provide init map).onClick(() {this.message new Map([[0, a], [1, b], [3, c], [4, d]])})Child()}.width(100%)}.height(100%)}
}
装饰Set类型变量 说明 从API version 11开始ProvideConsume支持Set类型。 在下面的示例中message类型为Setnumber点击Button改变message的值视图会随之刷新。
Component
struct Child {Consume message: Setnumberbuild() {Column() {ForEach(Array.from(this.message.entries()), (item: [number, string]) {Text(${item[0]}).fontSize(30)Divider()})Button(Consume init set).onClick(() {this.message new Set([0, 1, 2, 3, 4])})Button(Consume set new one).onClick(() {this.message.add(5)})Button(Consume clear).onClick(() {this.message.clear()})Button(Consume delete the first one).onClick(() {this.message.delete(0)})}.width(100%)}
}Entry
Component
struct SetSample {Provide message: Setnumber new Set([0, 1, 2, 3, 4])build() {Row() {Column() {Button(Provide init set).onClick(() {this.message new Set([0, 1, 2, 3, 4, 5])})Child()}.width(100%)}.height(100%)}
}
Provide_and_Consume支持联合类型实例
Provide和Consume支持联合类型和undefined和null在下面的示例中count类型为string | undefined点击父组件Parent中的Button改变count的属性或者类型Child中也会对应刷新。
Component
struct Child {// Consume装饰的变量通过相同的属性名绑定其祖先组件Ancestors内的Provide装饰的变量Consume count: string | undefined;build() {Column() {Text(count(${this.count}))Button(count(${this.count}), Child).onClick(() this.count Ancestors)}.width(50%)}
}Component
struct Parent {build() {Row({ space: 5 }) {Child()}}
}Entry
Component
struct Ancestors {// Provide装饰的联合类型count由入口组件Ancestors提供其后代组件Provide count: string | undefined Child;build() {Column() {Button(count(${this.count}), Child).onClick(() this.count undefined)Parent()}}
}
Provide支持allowOverride参数
allowOverrideProvide重写选项。 说明 从API version 11开始使用。 名称类型必填说明allowOverridestring否是否允许Provide重写。允许在同一组件树下通过allowOverride重写同名的Provide。如果开发者未写allowOverride定义同名的Provide运行时会报错。
Component
struct MyComponent {Provide({allowOverride : reviewVotes}) reviewVotes: number 10;
}
Component
struct GrandSon {// Consume装饰的变量通过相同的属性名绑定其祖先内的Provide装饰的变量Consume(reviewVotes) reviewVotes: number;build() {Column() {Text(reviewVotes(${this.reviewVotes})) // Text显示10Button(reviewVotes(${this.reviewVotes}), give 1).onClick(() this.reviewVotes 1)}.width(50%)}
}Component
struct Child {Provide({ allowOverride: reviewVotes }) reviewVotes: number 10;build() {Row({ space: 5 }) {GrandSon()}}
}Component
struct Parent {Provide({ allowOverride: reviewVotes }) reviewVotes: number 20;build() {Child()}
}Entry
Component
struct GrandParent {Provide(reviewVotes) reviewVotes: number 40;build() {Column() {Button(reviewVotes(${this.reviewVotes}), give 1).onClick(() this.reviewVotes 1)Parent()}}
}
在上面的示例中
GrandParent声明了Provide(reviewVotes) reviewVotes: number 40Parent是GrandParent的子组件声明Provide为allowOverride重写父组件GrandParent的Provide(reviewVotes) reviewVotes: number 40。如果不设置allowOverride则会抛出运行时报错提示Provide重复定义。Child同理。GrandSon在初始化Consume的时候Consume装饰的变量通过相同的属性名绑定其最近的祖先的Provide装饰的变量。GrandSon查找到相同属性名的Provide在祖先Child中所以Consume(reviewVotes) reviewVotes: number初始化数值为10。如果Child中没有定义与Consume同名的Provide则继续向上寻找Parent中的同名Provide值为20以此类推。如果查找到根节点还没有找到key对应的Provide则会报初始化Consume找不到Provide的报错。
常见问题
BuilderParam尾随闭包情况下Provide未定义错误
在此场景下CustomWidget执行this.builder()创建子组件CustomWidgetChild时this指向的是HomePage。因此找不到CustomWidget的Provide变量所以下面示例会报找不到Provide错误和BuilderParam连用的时候要谨慎this的指向。
错误示例
class Tmp {a: string
}Entry
Component
struct HomePage {Builderbuilder2($$: Tmp) {Text(${$$.a}测试)}build() {Column() {CustomWidget() {CustomWidgetChild({ builder: this.builder2 })}}}
}Component
struct CustomWidget {Provide(a) a: string abc;BuilderParambuilder: () void;build() {Column() {Button(你好).onClick((x) {if (this.a ddd) {this.a abc;}else {this.a ddd;}})this.builder()}}
}Component
struct CustomWidgetChild {Consume(a) a: string;BuilderParambuilder: ($$: Tmp) void;build() {Column() {this.builder({ a: this.a })}}
}
最后
有很多小伙伴不知道学习哪些鸿蒙开发技术不知道需要重点掌握哪些鸿蒙应用开发知识点而且学习时频繁踩坑最终浪费大量时间。所以有一份实用的鸿蒙HarmonyOS NEXT资料用来跟着学习是非常有必要的。
这份鸿蒙HarmonyOS NEXT资料包含了鸿蒙开发必掌握的核心知识要点内容包含了ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等鸿蒙HarmonyOS NEXT技术知识点。
希望这一份鸿蒙学习资料能够给大家带来帮助有需要的小伙伴自行领取限时开源先到先得~无套路领取
获取这份完整版高清学习路线请点击→纯血版全套鸿蒙HarmonyOS学习资料
鸿蒙HarmonyOS NEXT最新学习路线 HarmonOS基础技能 HarmonOS就业必备技能 HarmonOS多媒体技术 鸿蒙NaPi组件进阶 HarmonOS高级技能 初识HarmonOS内核 实战就业级设备开发 有了路线图怎么能没有学习资料呢小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙OpenHarmony 学习手册共计1236页与鸿蒙OpenHarmony 开发入门教学视频内容包含ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。
获取以上完整版高清学习路线请点击→纯血版全套鸿蒙HarmonyOS学习资料
《鸿蒙 (OpenHarmony)开发入门教学视频》 《鸿蒙生态应用开发V2.0白皮书》 《鸿蒙 (OpenHarmony)开发基础到实战手册》
OpenHarmony北向、南向开发环境搭建 《鸿蒙开发基础》
ArkTS语言安装DevEco Studio运用你的第一个ArkTS应用ArkUI声明式UI开发.…… 《鸿蒙开发进阶》
Stage模型入门网络管理数据管理电话服务分布式应用开发通知与窗口管理多媒体技术安全技能任务管理WebGL国际化开发应用测试DFX面向未来设计鸿蒙系统移植和裁剪定制…… 《鸿蒙进阶实战》
ArkTS实践UIAbility应用网络案例…… 获取以上完整鸿蒙HarmonyOS学习资料请点击→纯血版全套鸿蒙HarmonyOS学习资料
总结
总的来说华为鸿蒙不再兼容安卓对中年程序员来说是一个挑战也是一个机会。只有积极应对变化不断学习和提升自己他们才能在这个变革的时代中立于不败之地。