1. 总结
关键字描述@Builder轻量级的UI元素复用机制@BuilderParam引用@Builder函数,类似于solt插槽wrapBuilder封装@Builder函数为对象,可以组件内举行通报@Styles定义组件的重用样式 |@Extend扩展组件的样式stateStyles多态样式,类似CSS伪类@AnimatableExtend定义可动画属性@Require校验组件构造传参 2. @Builder装饰器
之前了解过自定义组件,自定义组件内部的UI布局固定,仅与使用方举行数据通报,如果我们有一个简朴的样式需要复用,但弄成一个自定义组件就会比较重。以是ArkUI提供了一种更轻量的UI元素复用机制:@Builder。
@Builder所装饰的函数依照build()函数语法规则,可以将重复使用的UI元素抽象成一个方法,在build()方法里举行调用。
被@Builder装饰的函数称为:自定义构建函数。
build()方法里只能调用 @Builder装饰的自定义构建函数。
2.1 自定义组件内自定义构建函数
根本使用:
- // 定义语法
- @Builder MyBuilderFunction(){ ... }
- // 使用方法
- this.MyBuilderFunction()
复制代码
- 只能在组件内部使用该自定义构建函数;
- 自定义构建函数写法和build()相同,this指向当前组件,可以直接使用组件的状态变量,不需要通过状态通报;
2.2 全局自定义构建函数
根本使用:
- // 定义语法
- @Builder function MyGlobalBuilderFunction(){ ... }
- // 使用方法
- MyGlobalBuilderFunction()
复制代码
- 全局定义的构建函数可以被整个应用获取,不允许使用this和bind方法;
- 如果不涉及组件状态变革,建议使用全局的自定义构建方法;
2.3 参数通报规则
自定义构建函数的参数通报分为按值通报和按引用通报,服从以下规则:
- 参数的类型必须与参数声明的类型一致,不允许undefined null和返回 undefined null的表达式;
- 自定义构造函数内部,不允许改变参数值。如果要改变参数值,且同步回调用点,使用@Link;
- @Builder内UI语法依照UI语法规则;
- 只有传入一个参数,且参数需要直接传入对象字面量才会按引用通报该参数,其余方式均按值通报;
按引用通报参数: 按引用通报参数时,通报的参数可为状态变量,状态变量的改变会引起@Builder方法内的UI刷新:
- class Tmp {
- paramA1: string = ''
- paramB1: string = ''
- }
- @Builder function overBuilder(params : Tmp) {...}
复制代码 示例:
- class Tmp {
- paramA1: string = ''
- }
- @Builder function overBuilder(params: Tmp) {
- Row() {
- Text(`UseStateVarByReference: ${params.paramA1} `)
- }
- }
- @Entry
- @Component
- struct Parent {
- @State label: string = 'Hello';
- build() {
- Column() {
- // Pass the this.label reference to the overBuilder component when the overBuilder component is called in the Parent component.
- // 传递的是状态变量
- overBuilder({ paramA1: this.label })
- Button('Click me').onClick(() => {
- // After Click me is clicked, the UI text changes from Hello to ArkUI.
- this.label = 'ArkUI';
- })
- }
- }
- }
复制代码 按引用通报参数时,如果在@Builder方法内调用自定义组件,ArkUI提供$$作为按引用通报参数的范式:
- class Tmp {
- paramA1: string = ''
- paramB1: string = ''
- }
- @Builder function overBuilder($$ : Tmp) {...}
复制代码 示例:
- class Tmp {
- paramA1: string = ''
- }
- @Builder function overBuilder($$: Tmp) {
- Row() {
- Column() {
- Text(`overBuilder===${$$.paramA1}`)
- // @Builder中又调用自定义组件,这里使用$$传递引用
- HelloComponent({message: $$.paramA1})
- }
- }
- }
- @Component
- struct HelloComponent {
- @Link message: string; // 还会建立双向绑定
- build() {
- Row() {
- Text(`HelloComponent===${this.message}`)
- Button("change")
- .onClick(()=>{
- // 点击这里的时候会改变两个Text的文本
- this.message = "Change in the HelloComponent"
- })
- }
- }
- }
- @Entry
- @Component
- struct Index {
- @State label: string = 'Hello';
- build() {
- Column() {
- // Pass the this.label reference to the overBuilder component when the overBuilder component is called in the Parent component.
- overBuilder({paramA1: this.label})
- Button('Click me').onClick(() => {
- // After Click me is clicked, the UI text changes from Hello to ArkUI.
- this.label = 'ArkUI';
- })
- }
- }
- }
复制代码 按值通报参数: 调用@Builder装饰的函数默认按值通报。当通报的参数为状态变量时,状态变量的改变不回引起@Builder方法内的UI刷新,以是如果使用状态变量时,保举使用引用通报:
- @Builder function overBuilder(paramA1: string) {
- Row() {
- Text(`UseStateVarByValue: ${paramA1} `)
- }
- }
- @Entry
- @Component
- struct Parent {
- @State label: string = 'Hello';
- build() {
- Column() {
- overBuilder(this.label)
- }
- }
- }
复制代码 2. @BuilderParam装饰器:引用@Builder函数
当开发者创建了自定义组件,并想对该组件添加特定功能时,例如在自定义组件中添加一个点击跳转操作,若直接在组件内嵌入变乱方法,将会导致全部引入该自定义组件的地方均增加了该功能。
为了办理这个问题,ArkUI引入了@BuilderParam装饰器,@BuilderParam用来装饰指向@Builder方法的变量,开发者可以在初始化自定义组件时对此属性赋值,为自定义组件增加特定的功能。该装饰器用于声明恣意UI描述的一个元素,类似slot占位符。
上面是来自官方文档的先容,其实就是类似于Vue框架的插槽slot。比如我们封装一个列表CellItem组件时,右边大概是箭头、Switch开关、文字等等,对于右边这部分内容,就可以使用@BuilderParam,让父组件定义CellItem组件右边的显示内容,把这部分内容“传”进去。
2.1 @BuilderParam的使用
@BuilderParam装饰的方法只能被自定义构建函数(@Builder装饰的方法)初始化,如果在API 11中和@Require结合使用,则必须父组件构造传参。
下面看一个简朴的使用示例:
- @Component
- struct Child {
- // 这个自定义构建函数只是为了本地初始化customBuilderParam
- @Builder customBuilder() {}
-
- // 会使用父组件@Builder装饰的方法初始化子组件的@BuilderParam,会覆盖这里的本地初始化
- @BuilderParam customBuilderParam: () => void = this.customBuilder;
- build() {
- Column() {
- // 展示父组件@Builder中的内容
- this.customBuilderParam()
- }
- }
- }
- @Entry
- @Component
- struct Parent {
- // 父组件中定义的自定义构建函数
- @Builder componentBuilder() {
- Text(`Parent builder `)
- }
- build() {
- Column() {
- // 将自定义构建函数传递给子组件
- Child({ customBuilderParam: this.componentBuilder })
- }
- }
- }
复制代码 示例效果图:
2.2 @BuilderParam和自定义构建函数参数要统一
@BuilderParam装饰的方法可以是有参数和无参数的两种形式,需与指向的@Builder方法类型匹配。@BuilderParam装饰的方法类型需要和@Builder方法类型一致。
- class Tmp{
- label:string = ''
- }
- // 全局的自定义构建函数
- @Builder function overBuilder($$ : Tmp) {
- Text($$.label)
- .width(400)
- .height(50)
- .backgroundColor(Color.Green)
- }
- @Component
- struct Child {
- label: string = 'Child'
- @Builder customBuilder() {}
- // 无参数类型,指向的componentBuilder也是无参数类型
- @BuilderParam customBuilderParam: () => void = this.customBuilder;
-
- // 有参数类型,指向的overBuilder也是有参数类型的方法
- @BuilderParam customOverBuilderParam: ($$ : Tmp) => void = overBuilder;
- build() {
- Column() {
- this.customBuilderParam()
- // 调用时传递了参数
- this.customOverBuilderParam({label: 'global Builder label' } )
- }
- }
- }
- @Entry
- @Component
- struct Parent {
- label: string = 'Parent'
- @Builder componentBuilder() {
- Text(`${this.label}`)
- }
- build() {
- Column() {
- this.componentBuilder()
- Child({ customBuilderParam: this.componentBuilder, customOverBuilderParam: overBuilder })
- }
- }
- }
复制代码 示例效果图:
2.3 this指向问题
- @Component
- struct Child {
- label: string = `Child`
- @Builder customBuilder() {}
- @Builder customChangeThisBuilder() {}
-
- @BuilderParam customBuilderParam: () => void = this.customBuilder;
- @BuilderParam customChangeThisBuilderParam: () => void = this.customChangeThisBuilder;
- build() {
- Column() {
- this.customBuilderParam()
- this.customChangeThisBuilderParam()
- }
- }
- }
- @Entry
- @Component
- struct Parent {
- label: string = `Parent`
- @Builder componentBuilder() {
- // 需要注意这里的this指向
- Text(`${this.label}`)
- }
- build() {
- Column() {
- // 直接调用组件内的自定义构建函数,this指向Parent组件;
- this.componentBuilder()
- // customBuilderParam,this指向child组件;
- // customChangeThisBuilderParam:箭头函数的this指向的是宿主对象,这里也是Parent组件;
- Child({ customBuilderParam: this.componentBuilder, customChangeThisBuilderParam: ():void=>{this.componentBuilder()} })
- }
- }
- }
复制代码 效果图:
2.4 尾随闭包
我们在使用Column Row等容器类组件时,会在 { } 中写子组件,这就是尾随闭包。可以将尾随闭包内的内容看做@Builder装饰的函数传给@BuilderParam:
- @Component
- struct CustomContainer {
- @Prop header: string = '';
- @Builder closerBuilder(){}
-
- // 使用父组件的尾随闭包{}(@Builder装饰的方法)初始化子组件@BuilderParam
- @BuilderParam closer: () => void = this.closerBuilder
- build() {
- Column() {
- Text(this.header)
- .fontSize(30)
- this.closer()
- }
- }
- }
- @Builder function specificParam(label1: string, label2: string) {
- Column() {
- Text(label1)
- .fontSize(30)
- Text(label2)
- .fontSize(30)
- }
- }
- @Entry
- @Component
- struct CustomContainerUser {
- @State text: string = 'header';
- build() {
- Column() {
- // 创建CustomContainer,在创建CustomContainer时,通过其后紧跟一个大括号“{}”形成尾随闭包
- // 作为传递给子组件CustomContainer @BuilderParam closer: () => void的参数
- CustomContainer({ header: this.text }) {
- Column() {
- specificParam('testA', 'testB')
- }.backgroundColor(Color.Yellow)
- .onClick(() => {
- this.text = 'changeHeader';
- })
- }
- }
- }
- }
复制代码 效果图:
需要注意:
- 使用尾随闭包的自定义组件内部有且仅有一个使用@BuilderParam装饰的属性;
- 此场景下自定义组件不支持通用属性;
3. wrapBuilder: 封装全局@Builder
全局@Builder作为wrapBuilder的参数返回WrappedBuilder对象,实现全局@Builder可以举行赋值和通报。
上面是官方的解释,简朴理解就是可以通过wrapBuilder函数将全局的@Builder函数封装成WrappedBuilder对象,通过这个对象的builder可以调用到全局@Builder函数,如许就可以将全局@Builder函数以包装对象的形式在组件间举行赋值和通报了。
3.1 接口阐明
wrapBuilder是一个模板函数,返回一个WrappedBuilder对象。
- // declare关键字主要用于声明变量、模块、函数或类的类型,不需要立即实现它们
- declare function wrapBuilder< Args extends Object[]>(builder: (...args: Args) => void): WrappedBuilder;
复制代码 同时WrappedBuilder对象也是一个模板类:
- // 模板参数Args extends Object[] 是需要包装的builder函数的参数列表
- declare class WrappedBuilder< Args extends Object[]> {
- builder: (...args: Args) => void;
- constructor(builder: (...args: Args) => void);
- }
复制代码 使用方法如下:
- let builderVar: WrappedBuilder<[string, number]> = wrapBuilder(MyBuilder)
- let builderArr: WrappedBuilder<[string, number]>[] = [wrapBuilder(MyBuilder)] //可以放入数组
复制代码 需要注意⚠️:
- wrapBuilder方法只能传入全局@Builder方法;
- wrapBuilder方法返回的WrappedBuilder对象的builder属性方法只能在struct(组件内部)内部使用;
3.2 使用场景1
将wrapBuilder赋值给globalBuilder,且把MyBuilder作为wrapBuilder参数,用来替换MyBuilder不能直接赋值给globalBuilder:
- // 这是一个全局的@Builder修饰的函数(自定义构建函数),需要两个参数,类型为string number
- @Builder
- function MyBuilder(value: string, size: number) {
- Text(value)
- .fontSize(size)
- }
- // 这里的[string, number]对应上面自定义构建函数的参数类型,是一个数组哦
- let globalBuilder: WrappedBuilder<[string, number]> = wrapBuilder(MyBuilder);
- @Entry
- @Component
- struct Index {
- @State message: string = 'Hello World';
- build() {
- Row() {
- Column() {
- // 这里可以直接调用builder,其实就是调用最上面的那个全局的@Builder自定义构建函数
- globalBuilder.builder(this.message, 50)
- }
- .width('100%')
- }
- .height('100%')
- }
- }
复制代码 3.3 使用场景2
自定义组件Index使用ForEach来举行差别@Builder函数的渲染,可以使用builderArr声明的wrapBuilder数组举行差别@Builder函数效果体现,团体代码会更加整洁:
- // 全局的自定义构建函数
- @Builder
- function MyBuilder(value: string, size: number) {
- Text(value)
- .fontSize(size)
- }
- // 全局的自定义构建函数
- @Builder
- function YourBuilder(value: string, size: number) {
- Text(value)
- .fontSize(size)
- .fontColor(Color.Pink)
- }
- // 这里使用一个数组存储这些WrappedBuilder:builderArr,需要全局的自定义构建函数的参数类型是一致的,如果不一致,那就封装成对象吧!
- const builderArr: WrappedBuilder<[string, number]>[] = [wrapBuilder(MyBuilder), wrapBuilder(YourBuilder)];
- @Entry
- @Component
- struct Index {
- // 组件内的自定义构建函数
- @Builder testBuilder() {
- // 循环渲染,调用item.builder进行渲染,这里会调用到顶部的全局自定义函数
- ForEach(builderArr, (item: WrappedBuilder<[string, number]>) => {
- item.builder('Hello World', 30)
- }
- )
- }
- build() {
- Row() {
- Column() {
- this.testBuilder()
- }
- .width('100%')
- }
- .height('100%')
- }
- }
复制代码 4. @Styles装饰器:定义组件重用样式
如果每个组件的样式都需要单独设置,在开发过程中会出现大量代码在举行重复样式设置,虽然可以复制粘贴,但是为了代码简便性和后续方便维护,鸿蒙提供了可以提炼公共样式举行复用的装饰器@Styles。
@Styles装饰器可以将多条样式设置提炼成一个方法,直接在组件声明的位置调用,通过@Styles装饰器可以快速定义并复用自定义样式。
上面是官方的阐明,简朴的来说就是把多个组件通用的属性和方法封装成一个方法,在创建组件的时候可以直接使用,避免重复写样式代码;嗯。。。类似前端CSS中按class分类吧。
4.1 装饰器使用阐明
- 当前@Styles仅支持通用属性和通用变乱;
- @Styles方法不支持参数;
- // 错误❌: @Styles不支持参数
- @Styles function globalFancy (value: number) {
- .width(value)
- }
复制代码
- @Styles可以定义在组件内或全局,在全局定义时需要在方法名前面添加function关键字,组件内定义时则不需要添加function关键字;
- 只能在当前文件内使用,不支持export;
- // 全局
- @Styles function functionName() { ... }
- // 在组件内
- @Component
- struct FancyUse {
- @Styles fancy() {
- .height(100)
- }
- }
复制代码
- 定义在组件内的@Styles可以通过this访问组件的常量和状态变量,并可以在@Styles里通过变乱来改变状态变量的值,示例如下:
- @Component
- struct FancyUse {
- @State heightValue: number = 100
-
- @Styles fancy() {
- .height(this.heightValue)
- .backgroundColor(Color.Yellow)
- .onClick(() => {
- this.heightValue = 200
- })
- }
- }
复制代码
- 组件内@Styles的优先级高于全局的@Styles,框架会优先查找当前组件内的@Styles,如果找不到,就会全局查找;
4.2 使用场景
- // 定义在全局的@Styles封装的样式
- @Styles function globalFancy () {
- .width(150)
- .height(100)
- .backgroundColor(Color.Pink)
- }
- @Entry
- @Component
- struct FancyUse {
- @State heightValue: number = 100
-
- // 定义在组件内的@Styles封装的样式
- @Styles fancy() {
- .width(200)
- .height(this.heightValue)
- .backgroundColor(Color.Yellow)
- .onClick(() => {
- this.heightValue = 200
- })
- }
- build() {
- Column({ space: 10 }) {
- // 使用全局的@Styles封装的样式
- Text('FancyA')
- .globalFancy()
- .fontSize(30)
- // 使用组件内的@Styles封装的样式
- Text('FancyB')
- .fancy()
- .fontSize(30)
- }
- }
- }
复制代码 5. @Extend装饰器:定义扩展组件样式
上面的@Styles用于样式的扩展,在@Styles的底子上,鸿蒙又提供了@Extend,用于扩展原生组件样式。相比于@Styles提供了更多的扩展的能力。
5.1 使用阐明
语法:
- @Extend(UIComponentName) function functionName { ... }
复制代码 使用规则:
- 和@Styles差别,@Extend仅支持在全局定义。并且也只能在当前文件中使用;
- 和@Styles差别,@Extend支持封装指定的组件的私有属性和私有变乱,以及预定义相同组件的@Extend的方法;
- // @Extend(Text)可以支持Text的私有属性fontColor
- @Extend(Text) function fancy () {
- .fontColor(Color.Red)
- }
- // superFancyText可以调用预定义的fancy
- @Extend(Text) function superFancyText(size:number) {
- .fontSize(size)
- .fancy()
- }
复制代码
- 和@Styles差别,@Extend装饰的方法支持参数,开发者可以在调用时通报参数,调用依照TS方法传值和调用;
- // xxx.ets
- @Extend(Text) function fancy (fontSize: number) {
- .fontColor(Color.Red)
- .fontSize(fontSize)
- }
- @Entry
- @Component
- struct FancyUse {
- build() {
- Row({ space: 10 }) {
- Text('Fancy')
- .fancy(16)
- Text('Fancy')
- .fancy(24)
- }
- }
- }
复制代码
- @Extend装饰的方法的参数可以为function,作为Event变乱的句柄:
- @Extend(Text) function makeMeClick(onClick: () => void) {
- .backgroundColor(Color.Blue)
- .onClick(onClick)
- }
- @Entry
- @Component
- struct FancyUse {
- @State label: string = 'Hello World';
- onClickHandler() {
- this.label = 'Hello ArkUI';
- }
- build() {
- Row({ space: 10 }) {
- Text(`${this.label}`)
- .makeMeClick(() => {this.onClickHandler()})
- }
- }
- }
复制代码
- @Extend的参数可以为状态变量,当状态变量改变时,UI可以正常的被刷新渲染
- @Extend(Text) function fancy (fontSize: number) {
- .fontColor(Color.Red)
- .fontSize(fontSize)
- }
- @Entry
- @Component
- struct FancyUse {
-
- @State fontSizeValue: number = 20
-
- build() {
- Row({ space: 10 }) {
- Text('Fancy')
- .fancy(this.fontSizeValue)
- .onClick(() => {
- this.fontSizeValue = 30
- })
- }
- }
- }
复制代码 5.2 使用场景
以下示例声明了3个Text组件,每个Text组件均设置了fontStyle、fontWeight和backgroundColor样式:
- @Entry
- @Component
- struct FancyUse {
- @State label: string = 'Hello World'
- build() {
- Row({ space: 10 }) {
- Text(`${this.label}`)
- .fontStyle(FontStyle.Italic)
- .fontWeight(100)
- .backgroundColor(Color.Blue)
- Text(`${this.label}`)
- .fontStyle(FontStyle.Italic)
- .fontWeight(200)
- .backgroundColor(Color.Pink)
- Text(`${this.label}`)
- .fontStyle(FontStyle.Italic)
- .fontWeight(300)
- .backgroundColor(Color.Orange)
- }.margin('20%')
- }
- }
复制代码 可以使用@Extend将样式组合复用,示例如下:
- // 组合
- @Extend(Text) function fancyText(weightValue: number, color: Color) {
- .fontStyle(FontStyle.Italic)
- .fontWeight(weightValue)
- .backgroundColor(color)
- }
- @Entry
- @Component
- struct FancyUse {
- @State label: string = 'Hello World'
- build() {
- Row({ space: 10 }) {
- Text(`${this.label}`)
- .fancyText(100, Color.Blue)
- Text(`${this.label}`)
- .fancyText(200, Color.Pink)
- Text(`${this.label}`)
- .fancyText(300, Color.Orange)
- }.margin('20%')
- }
- }
复制代码 6. stateStyles:多态样式
@Styles和@Extend仅仅应用于静态页面的样式复用,stateStyles可以依据组件的内部状态的差别,快速设置差别的样式,可以称为多态样式。
就是类似CSS的伪类,针对于按钮点击、按压、获取焦点等,分别设置差别的样式;
6.1 概述
stateStyles是属性方法,可以根据UI内部状态来设置样式,类似css伪类,但是语法差别。ArkUI提供以下5种状态:
- focused
- normal
- pressed
- disabled
- selected
6.2 底子使用场景
下面的示例展示了stateStyles最根本的使用场景。Button1处于第一个组件,Button2处于第二个组件。按压时显示为pressed态指定的玄色。使用Tab键走焦,先是Button1获焦并显示为focus态指定的粉色。当Button2获焦的时候,Button2显示为focus态指定的粉色,Button1失焦显示normal态指定的红色。
- @Entry
- @Component
- struct StateStylesSample {
- build() {
- Column() {
- Button('Button1')
- .stateStyles({
- focused: {
- .backgroundColor(Color.Pink)
- },
- pressed: {
- .backgroundColor(Color.Black)
- },
- normal: {
- .backgroundColor(Color.Red)
- }
- })
- .margin(20)
- Button('Button2')
- .stateStyles({
- focused: {
- .backgroundColor(Color.Pink)
- },
- pressed: {
- .backgroundColor(Color.Black)
- },
- normal: {
- .backgroundColor(Color.Red)
- }
- })
- }.margin('30%')
- }
- }
复制代码 6.3 @Styles和stateStyles联合使用
以下示例通过@Styles指定stateStyles的差别状态:
- @Entry
- @Component
- struct MyComponent {
- @Styles normalStyle() {
- .backgroundColor(Color.Gray)
- }
- @Styles pressedStyle() {
- .backgroundColor(Color.Red)
- }
- build() {
- Column() {
- Text('Text1')
- .fontSize(50)
- .fontColor(Color.White)
- .stateStyles({
- normal: this.normalStyle,
- pressed: this.pressedStyle,
- })
- }
- }
- }
复制代码 7. @AnimatableExtend装饰器:定义可动画属性
@AnimatableExtend装饰器用于自定义可动画的属性方法,在这个属性方法中修改组件不可动画的属性。在动画执行过程时,通过逐帧回调函数修改不可动画属性值,让不可动画属性也能实现动画效果。
- 可动画属性:如果一个属性在animation属性前调用,改变这个属性的值可以见效animation属性的动画效果,这个属性称为可动画属性,比如height、width、backgroundColor、translate属性,Text组件的fontSize属性等;
- 不可动画属性:如果一个属性方法在animation属性前调用,改变这个属性的值不能见效animation属性的动画效果,这个属性称为不可动画属性,比如Polyline组件的points属性等;
7.1 使用阐明
- // 1. @AnimatableExtend仅支持在全局定义;
- // 2. 函数参数类型必须为number类型或者实现AnimtableArithmetic<T>接口的自定义类型;
- // 3. 函数体内只能调用@AnimatableExtend括号组件的属性方法;
- @AnimatableExtend(UIComponentName) function functionName(value: typeName) {
- .propertyName(value)
- }
复制代码
7.2 使用场景
实现字体大小的动画效果:
- @AnimatableExtend(Text) function animatableFontSize(size: number) {
- .fontSize(size)
- }
- @Entry
- @Component
- struct AnimatablePropertyExample {
- @State fontSize: number = 20
- build() {
- Column() {
- Text("AnimatableProperty")
- .animatableFontSize(this.fontSize)
- .animation({duration: 1000, curve: "ease"})
- Button("Play")
- .onClick(() => {
- this.fontSize = this.fontSize == 20 ? 36 : 20
- })
- }.width("100%")
- .padding(10)
- }
- }
复制代码 8. @Require装饰器:校验构造传参
@Require装饰器不能单独使用,和@Prop和@BuilderParam配合使用。在构造自定义组件时,用@Require修饰的@Prop和@BuilderParam变量,必须在构造时传参。
@Require装饰器仅用于装饰struct内的@Prop和@BuilderParam成员状态变量。
8.1 使用场景
当Child组件内使用@Require装饰器和@Prop或者@BuilderParam结合使用时,父组件Index在构造Child时必须传参,否则编译不通过。
- @Entry
- @Component
- struct Index {
- @State message: string = 'Hello World';
- @Builder buildTest() {
- Row() {
- Text('Hello, world')
- .fontSize(30)
- }
- }
- build() {
- Row() {
- Child({ initMessage: this.message, message: this.message,
- buildTest: this.buildTest, initbuildTest: this.buildTest })
- }
- }
- }
- @Component
- struct Child {
- @Builder buildFuction() {
- Column() {
- Text('initBuilderParam')
- .fontSize(30)
- }
- }
- // 使用@Require标识父组件在构造Child组件时,必须使用构造传参;
- @Require @BuilderParam buildTest: () => void;
- @Require @BuilderParam initbuildTest: () => void = this.buildFuction;
- @Require @Prop initMessage: string = 'Hello';
- @Require @Prop message: string;
- build() {
- Column() {
- Text(this.initMessage)
- .fontSize(30)
- Text(this.message)
- .fontSize(30)
- this.initbuildTest();
- this.buildTest();
- }
- .width('100%')
- .height('100%')
- }
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |