【高心星出品】
@BuildParam 自定义插槽
当开发者需要自定义组件或是封装组件的时候,经常要根据需求定制布局界面效果,这个时候就需要根据不同条件构建不同的布局效果,@BuildParam 配合 @Build 就可以实现将布局界面作为参数来进行传递。
插槽的声明和调用
需要在子组件中声明一个插槽并且在 build 函数中调用该插槽,插槽类型为()=>void 类型,还需要给该插槽一个空的 @builder 构建函数。
@BuilderParam slot:()=>void=this.test //声明一个插槽 插槽函数为()=>void类型@Builder test(){} //给插槽一个默认值 否则无法执行
复制代码
build() {Column(){ Text(this.ison?'开':'关') //子组件布局元素 this.slot()//插槽 需要父组件传递}.width('100%') }
复制代码
完整的子组件代码:
@Componentexport struct child{ @Link ison:boolean @BuilderParam slot:()=>void=this.test @Builder test(){} build() { Column(){ Text(this.ison?'开':'关') this.slot() }.width('100%') }}
复制代码
插槽的初始化
需要在父组件中定义 @builder 构建函数,并将该构建函数初始化给子组件的插槽。
父组件定义的构建函数:
@Builder child() //插槽布局{ Row(){ }.width('100%') .height('40%') .margin({top:20}) .backgroundColor(this.ison?Color.Red:Color.Black)}@Builder child1()//插槽布局{ Row(){ }.width('100%') .height('40%') .margin({top:20}) .backgroundColor(Color.Blue) .borderRadius(this.ison?'50%':0)}
复制代码
父组件调用子组件:
child({ison:this.ison,slot:this.child1})//子组件调用并初始化插槽 .margin({top:20}).border({width:2})
复制代码
完整父组件代码:
import { child } from '../component/chacao';
@Entry@Componentstruct Parent { @State ison:boolean=false @Builder child() //插槽布局 { Row(){ }.width('100%') .height('40%') .margin({top:20}) .backgroundColor(this.ison?Color.Red:Color.Black) } @Builder child1()//插槽布局 { Row(){ }.width('100%') .height('40%') .margin({top:20}) .backgroundColor(Color.Blue) .borderRadius(this.ison?'50%':0) } build() { Column(){ Toggle({type:ToggleType.Switch,isOn:this.ison}) //父组件元素 .onChange((isck)=>{ this.ison=isck }) child({ison:this.ison,slot:this.child1})//子组件调用 .margin({top:20}).border({width:2}) } .height('100%') .width('100%') .backgroundColor(Color.Yellow) .justifyContent(FlexAlign.Center) }}
复制代码
this 指向问题
由于插槽是在子组件中定义,子组件中调用,而插槽是在父组件中初始化的,所以就牵涉到 this 指向问题。原则上在哪里调用 this 指向哪里,所以父组件构建函数中的 this 执行并非是父组件而是子组件,也就是案例中构建函数中 this 指的是子组件,这里的“this.ison”指定的是子组件的全局变量 ison 而不是父组件的。但是编译问题也要在父组件中定义 ison 并且要求两者进行双向绑定(所以可以看到 ison 是 @link 装饰的)。
@Builder child() //插槽布局{ Row(){ }.width('100%') .height('40%') .margin({top:20}) .backgroundColor(this.ison?Color.Red:Color.Black) //child中的ison变量}@Builder child1()//插槽布局{ Row(){ }.width('100%') .height('40%') .margin({top:20}) .backgroundColor(Color.Blue) .borderRadius(this.ison?'50%':0) //child中的ison变量}
复制代码
如何才能使用父组件的 this 呢?
需要在调用子组件的时候加上闭包函数。
build() { Column(){ Toggle({type:ToggleType.Switch,isOn:this.ison}) //父组件元素 .onChange((isck)=>{ this.ison=isck }) child({ison:this.ison,slot:()=>{this.child1()}})//子组件调用 这个时候this就是当前的父组件了 .margin({top:20}).border({width:2}) } .height('100%') .width('100%') .backgroundColor(Color.Yellow) .justifyContent(FlexAlign.Center) }}
复制代码
评论