建立微网站,魔方的网站,公司营销策划方案,医院门户网站模板下载一、Provide Consume
父组件与子组件的子组件(官方叫法#xff1a;后代组件)双向同步数据#xff08;即#xff0c;父组件与后代组件可以相互操作 Provide 修饰的数据#xff09;
注意#xff1a;Provide 与 Consume声明的变量名必须一致。
import {TestChild } from .…一、Provide Consume
父组件与子组件的子组件(官方叫法后代组件)双向同步数据即父组件与后代组件可以相互操作 Provide 修饰的数据
注意Provide 与 Consume声明的变量名必须一致。
import {TestChild } from ./TestChild
Entry //这是一个页面
Component // 页面中有一个视图容器即根布局 Row()
struct Index {Provide msg: string 混沌count: number 0build(){Row(){Column( {space : 20} ) {Text(this.msg).fontSize(30).fontWeight(FontWeight.Bold)Button(Parent 更新文字内容).onClick( (){this.msg Hello World (this.count)})TestChild()}.width(100%)}.height(100%)}
}TestChild 嵌套 TestChild2, TestChild2嵌套TestChild3
Component
export struct TestChild{build(){TestChild2(){.width(100%).backgroundColor(Color.Red).align(Alignment.Center)}}
}Component
export struct TestChild2{build(){TestChild3()}
}Component
export struct TestChild3{Consume msg: stringcount: number 0build(){Column(){Text(this.msg).fontSize(30)Button(TestChild2 更新文字内容).onClick( (){this.msg HarmonyOS - Child (this.count)}) }.backgroundColor(Color.Pink)}
}二、Observed ObjectLink
父组件与嵌套对象或数组进行双向向同步数据。
说明实际业务研发中封装好多类与 Component 修饰的组件无关这个时候如果要让父组件和 嵌套对象进行数据同步前边所介绍的所有装饰器是无法做到的。 子组件中ObjectLink装饰器装饰的状态变量用于接收Observed装饰的类实例和父组件中对应的状态变量建立双向数据绑定。 单独使用Observed是没有任何作用的需要搭配ObjectLink或者Prop初始状态。 // 引起此问题初始化代码
State b: ClassB new ClassB(new ClassA(0));
// 修改
State a: ClassA new ClassA(0)
State b: ClassB new ClassB(a)import {ClassA, ClassB, TestChild } from ./TestChild
Entry //这是一个页面
Component //页面中有一个视图容器即根布局 Row()
struct Index {State b: ClassB new ClassB(new ClassA(0));build() {Row() {Column( {space : 20} ) {Text(this.b.a.c ).fontSize(30).fontWeight(FontWeight.Bold)Button(Parent 更新文字内容).onClick( (){this.b.a.c 1;})TestChild({a: this.b.a})}.width(100%)}.height(100%)}
}Component
export struct TestChild {ObjectLink a: ClassA;build(){Column(){Text(this.a.c ).fontSize(30)Button(TestChild2 更新文字内容).onClick( (){this.a.c 1;} )}.backgroundColor(Color.Pink)}
} Observed
export class ClassA {public c: number;constructor(c: number) {this.c c;}
}export class ClassB {public a: ClassA;constructor(a: ClassA) {this.a a;}
}三、Watch
关注某个变量状态发生变化。
注意监听的这个变量不要放在回调方法中让其发生二次变化容易导致死循环。
import {ClassA, ClassB, TestChild } from ./TestChildEntry //这是一个页面
Component //页面中有一个视图容器即根布局 Row()
struct Index {State msg: string 混沌State index: number 0;build(){Row(){Column( {space : 20} ) {Text(this.msg this.index).fontSize(30).fontWeight(FontWeight.Bold)Button(Parent 更新文字内容).onClick( (){this.index})TestChild({count: this.index})}.width(100%)}.height(100%)}
}NOTE使用 Prop 修饰的原因感知父组件改变 count 值。
Component
export struct TestChild{Prop Watch(onCountUpdated) count: number;State total: number 0;// Watch 回调onCountUpdated(propName: string): void {this.total 1;}build(){Column(){Text(HarmonyOS - Child this.total).fontSize(30)Button(TestChild2 更新文字内容).onClick( (){this.count})}.backgroundColor(Color.Pink)}
}四、LocalStorageLink LocalStorageProp
LocalStorage是页面级的UI状态存储通过Entry装饰器接收的参数可以在页面内共享同一个LocalStorage实例。LocalStorage也可以在UIAbility内页面间共享状态。
LocalStorage在场景使用过程中包含了两个装饰器即LocalStorageLink 和 LocalStorageProp。
import { TestChild } from ./TestChild;// 创建新实例并使用给定对象初始化
let storage new LocalStorage({ PropA: 47 });// 使LocalStorage可从Component组件访问
Entry(storage)
Component
struct Index {// LocalStorageLink变量装饰器与LocalStorage中的PropA属性建立双向绑定LocalStorageLink(PropA) count: number 1;build(){Row(){Column( {space : 20} ){Text(混沌 this.count).fontSize(30).fontWeight(FontWeight.Bold)Button(Parent 更新文字内容).onClick( (){this.count})TestChild() }.width(100%)}.height(100%)}
}Component
export struct TestChild {// LocalStorageLink变量装饰器与LocalStorage中的PropA属性建立双向绑定LocalStorageLink(PropA) count: number 1;build() {Column( {space : 20} ) {Text(HarmonyOS - Child this.count).fontSize(30).fontWeight(FontWeight.Bold)Button(TestChild2 更新文字内容).onClick( (){this.count}) }.width(100%).backgroundColor(Color.Pink)}
}总结本例展示了:
使用构造函数创建LocalStorage实例storage使用Entry装饰器将storage添加到 Index 顶层组件中LocalStorageLink绑定LocalStorage对给定的属性建立双向数据同步
import { TestChild } from ./TestChild;// 创建新实例并使用给定对象初始化
let storage new LocalStorage({ PropA: 47 });// 使LocalStorage可从Component组件访问
Entry(storage)
Component
struct Index {// LocalStorageLink变量装饰器与LocalStorage中的PropA属性建立双向绑定LocalStorageProp(PropA) count: number 1;build() {Row() {Column( {space : 20} ) {Text(混沌 this.count).fontSize(30).fontWeight(FontWeight.Bold)Button(Parent 更新文字内容).onClick( (){this.count})TestChild() }.width(100%)}.height(100%)}
}let storage LocalStorage.GetShared()Component
export struct TestChild{// LocalStorageLink变量装饰器与LocalStorage中的PropA属性建立双向绑定LocalStorageLink(PropA) count: number 1;build() {Column( {space : 20} ) {Text(HarmonyOS - Child this.count).fontSize(30).fontWeight(FontWeight.Bold)Button(TestChild2 更新文字内容).onClick( (){this.count})}.width(100%).backgroundColor(Color.Pink)}
}
LocalStorageLink(key)是和LocalStorage中key对应的属性建立双向数据同步
本地修改发生该修改会被写回LocalStorage中 LocalStorage中的修改发生后该修改会被同步到所有绑定LocalStorage对应key的属性上包括单向LocalStorageProp和通过prop创建的单向绑定变量、双向LocalStorageLink和通过link创建的双向绑定变量变量。
这个例子中TestChild组件使用了LocalStorageLInk, 当其值发生变化时会同时影响到父布局使用到 LocalStorageProp 装饰器的变量值即 子组件的变量通过LocalStorage可以影响到相应的父组件变量值但父组件的相关变量值是无法影响到子组件的变量值
五、StorageLink StorageProp
AppStorage是应用全局的UI状态存储是和应用的进程绑定的由UI框架在应用程序启动时创建为应用程序UI状态属性提供中央存储。
AppStorage在场景使用过程中包含了两个装饰器即StorageLink 和 StorageProp
和AppStorage不同的是LocalStorage是页面级的通常应用于页面内的数据共享。而AppStorage是应用级的全局状态共享还相当于整个应用的“中枢”持久化数据PersistentStorage和环境变量Environment都是通过和AppStorage中转才可以和UI交互。
注⚠️AppStorage 和 LocalStorage是互不影响的
import { TestChild } from ./TestChild;
AppStorage.SetOrCreate(PropA, 47);// 创建新实例并使用给定对象初始化
let storage new LocalStorage();// 使LocalStorage可从Component组件访问
Entry(storage)
Component
struct Index {// LocalStorageLink变量装饰器与LocalStorage中的PropA属性建立双向绑定StorageLink(PropA) count: number 1;LocalStorageLink(PropA) countL: number 1;build() {Row(){Column( {space : 20} ) {Text(AppStorage this.count).fontSize(30).fontWeight(FontWeight.Bold)Button(更新AppStorage内容).onClick( (){this.count})Text(LocalStorage this.countL).fontSize(30).fontWeight(FontWeight.Bold)Button(更新LocalStorage内容).onClick( (){this.countL})TestChild() }.width(100%)}.height(100%)}
}Component
export struct TestChild {// LocalStorageLink变量装饰器与LocalStorage中的PropA属性建立双向绑定StorageLink(PropA) count: number 1;build(){Column( {space : 20} ) {Text(HarmonyOS - Child this.count).fontSize(30).fontWeight(FontWeight.Bold)Button(TestChild2 更新文字内容).onClick( (){this.count})}.width(100%).backgroundColor(Color.Pink) }
}六、Builder
Builder 用于UI元素复用开发者可以将重复使用的UI元素抽象成一个方法在build方法里调用。
总结
值引用方式可以感知父组件的状态变化值传递方式无法感知父组件的状态变化
Entry
Component
struct Index {State count: number 1;Builder BuilderOne($$: { paramA1: number }) {Column() {Text(组件1值引用: ${$$.paramA1} ).fontSize(20)}.width(100%).backgroundColor(Color.Pink)}Builder BuilderTwo(paramA1: number) {Column() {Text(组件2值传递: ${paramA1} ).fontSize(20)}.width(100%).backgroundColor(Color.Pink)}build() {Row() {Column({ space: 20 }) {Text(混沌 this.count).fontSize(30).fontWeight(FontWeight.Bold)Button(更新).onClick(() {this.count})this.BuilderOne({ paramA1: this.count })this.BuilderTwo(this.count)}.width(100%)}.height(100%)}
}
七、BuilderParam
当开发者创建了自定义组件并想对该组件添加特定功能时例如在自定义组件中添加一个点击跳转操作。若直接在组件内嵌入事件方法将会导致所有引入该自定义组件的地方均增加了该功能。为解决此问题ArkUI引入了BuilderParam装饰器BuilderParam用来装饰指向Builder方法的变量开发者可在初始化自定义组件时对此属性进行赋值为自定义组件增加特定的功能。该装饰器用于声明任意UI描述的一个元素类似slot占位符。
import Prompt from system.prompt;
import { TestChild } from ./TestChild;Entry
Component
struct Index {Builder BuilderOne() {TestChild( {msg: BuilderOne 视图} ) {Text(1).fontColor(Color.Red)}}Builder BuilderTwo() {Stack(){TestChild( {msg: BuilderTwo 视图} ) {Text(1).fontColor(Color.Red)Text(2).fontColor(Color.Red)}}.onClick( () {Prompt.showToast({message: 点了 BuilderTwo})})}BuilderParam aBuilder0: () void this.BuilderOneBuilderParam aBuilder1: () void this.BuilderTwobuild(){Column({ space: 20 }) {this.aBuilder0()this.aBuilder1()TestChild( {msg: 中国} ) {Text(1).fontColor(Color.Red)})}.width(100%).height(100%).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)}}Component
export struct TestChild {msg: stringBuilderParam aB0: () {}build(){Column( {space : 20} ) {this.aB0()Text(TestChild上下有 this.msg).fontSize(20).fontWeight(FontWeight.Bold) this.aB0() }.width(100%).backgroundColor(Color.Pink)}
}BuilderParam 既可以指向一个对象 也可以指向Builder修饰的方法
带占位的自定义视图是没法响应onClick事件的所以在上面的示例中将子组件外边再添加了一个容器组件用来进行点击事件响应
八、Styles
如果每个组件的样式都需要单独设置在开发过程中会出现大量代码在进行重复样式设置虽然可以复制粘贴但为了代码简洁性和后续方便维护可使用装饰器Styles。
import Prompt from system.prompt;Entry
Component
struct Index {//仅支持公共属性Styles fancy() {.width(200).height(300).backgroundColor(Color.Pink).onClick(() {Prompt.showToast({message: I am fancy})})}build() {Column({ space: 20 }) {Text(Styles).textAlign(TextAlign.Center).fancy()}.width(100%).height(100%).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)}
}总结
Styles 当前仅支持通用属性Styles 修饰的方法不支持参数引用**Styles** 修饰的方法时建议放在最后比如Text().fancy().textAlign(....) 应该变为 Text().textAlign(....) .fancy()
九、Extend
用于扩展原生组件样式。
注意⚠️
原生指的是ArkTS写的组件扩展不是新定义增加不存在的属性
import Prompt from system.prompt;//仅支持公共属性
Styles function fancy() {.width(200).height(300).backgroundColor(Color.Pink).onClick(() {Prompt.showToast({message: I am fancy})})
}Extend(Text) function superFancy(size:number, onClick?: () void) {.fontSize(size).textAlign(TextAlign.Center).fancy().onClick(onClick)
}Entry
Component
struct Index {onClickHandler() {Prompt.showToast({message: fancy出去了})}build(){Column({ space: 20 }) {Text(Styles).superFancy(30, this.onClickHandler.bind(this))}.width(100%).height(100%).justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)}
}总结
Extend 在 Styles基础上增加了传参特性Extend 必须定义为全局支持封装指定组件的私有属性和私有事件和预定义相同组件的Extend的方法
十、Concurrent
在使用TaskPool时执行的并发函数需要使用该装饰器修饰否则无法通过相关校验。
import taskpool from ohos.taskpool;Concurrent
function add(num1: number, num2: number): number {return num1 num2;
}async function ConcurrentFunc(): Promisevoid {try {let task: taskpool.Task new taskpool.Task(add, 1, 2);console.info(taskpool res is: await taskpool.execute(task));}catch (e) {}
}Entry
Component
struct Index {State message: string Hello Worldbuild(){Row(){Column(){Text(this.message).fontSize(50).fontWeight(FontWeight.Bold).onClick(() {ConcurrentFunc();})}.width(100%)}.height(100%)}
}十一、拓展阅读
《HarmonyOS 进阶专栏》