【高心星出品】
@BuildParam 自定义插槽
当开发者需要自定义组件或是封装组件的时候,经常要根据需求定制布局界面效果,这个时候就需要根据不同条件构建不同的布局效果,@BuildParam 配合 @Build 就可以实现将布局界面作为参数来进行传递。
插槽的声明和调用
需要在子组件中声明一个插槽并且在 build 函数中调用该插槽,插槽类型为()=>void 类型,还需要给该插槽一个空的 @builder 构建函数。
@BuilderParam slot:()=>void=this.test //声明一个插槽 插槽函数为()=>void类型
@Builder test(){} //给插槽一个默认值 否则无法执行
复制代码
build() {
Column(){
Text(this.ison?'开':'关') //子组件布局元素
this.slot()//插槽 需要父组件传递
}.width('100%')
}
复制代码
完整的子组件代码:
@Component
export 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
@Component
struct 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)
}
}
复制代码
评论