在ArkUI的ETS中实现【插槽】的功能

开发 前端
插槽是一套内容分发的API,当组件渲染的时候,将会被替换为“Your Profile”。插槽内可以包含任何模板代码。

[[436541]]

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

距离ETS的发布也有一段时间,也有不少小伙伴通过ETS制作出很多精美的页面,但在我查阅ETS的组件和API中发现,现有版本的ETS并没有插槽的功能。经过一段时间的探索终于找到曲线救国方式实现插槽功能,得以让组件之间进行解耦。

什么是插槽

了解插槽的小伙伴可以跳过

vue官方定义是:插槽是一套内容分发的API,当组件渲染的时候, 将会被替换为“Your Profile”。插槽内可以包含任何模板代码。

通俗一点就是插槽就像一个占位符,将组件外的内容通过API分发至组件内。

实现步骤

定义一个slot类

旨在提供一个具名的插槽,故定义一个slot类做后续委托。这不是实现的关键点,也可不定义。

  1. class Slot{ 
  2.   name:string="default" 
  3.   builder:any 
  4.  
  5.   constructor (name:string,builder:any){ 
  6.     this.name=name
  7.     this.builder=builder 
  8.   } 

创建一个组件CompA

创建一个自定义组件CompA,并提供两个具名插槽的处理,一个defualt,一个slot2。

  1. @Component 
  2. struct CompA{ 
  3.   @State text:string="" 
  4.   @State data:string[]=[] 
  5.   @State slot:Slot=new Slot(null
  6.   build(){ 
  7.     Column(){ 
  8.       Column(){ 
  9.         Text("CompA组件内的内容"
  10.         .fontColor("#00F"
  11.         .fontSize(16) 
  12.         .margin(10) 
  13.       } 
  14.       Column(){ 
  15.         Row(){ 
  16.           if(this.slot.name=="default"){ 
  17.             ForEach(["这是默认插槽【default】"], 
  18.               this.slot.builder) 
  19.           } 
  20.           if(this.slot.name=="slot2"){ 
  21.             ForEach(this.data, 
  22.               this.slot.builder) 
  23.           } 
  24.         } 
  25.       } 
  26.     } 
  27.   } 

构建页面的组件

构建一个Index的页面,在页面内创建两个Buider bulder1 ,builder2,并实例化两个Slot类slot1、slot2,将builder1,builder2分别给到slot1,slot2。

builder1内通过Text组件显示一段文字。

builder2内通构建稍微复杂一点的模型,设置一个文字和二维码。

  1. @Entry 
  2. @Component 
  3. struct Index { 
  4.   @Builder builder1(str:string){ 
  5.     Text(str).fontSize(18).fontColor("#f00"
  6.   } 
  7.  
  8.   @Builder builder2(obj:any){ 
  9.     Column(){ 
  10.       Row(){ 
  11.         Text(obj.title).fontSize(16) 
  12.       } 
  13.       Row(){ 
  14.         QRCode(obj.title).width(100).height(100) 
  15.       }.margin(10) 
  16.     }.margin(10) 
  17.   } 
  18.  
  19.    slot1:Slot=new Slot(this.builder1) 
  20.    slot2:Slot=new Slot(this.builder2,"slot2"
  21.  
  22.   build() { 
  23.     Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 
  24.       Column(){ 
  25.          CompA(){ 
  26.            Text("这样是不会显示的").fontSize(24) 
  27.          } 
  28.         CompA({slot:this.slot1}) 
  29.         CompA({slot:this.slot2,data:[{title:"这是第二个插槽"},{title:"http://www.baidu.com"}]}) 
  30.       } 
  31.     } 
  32.     .width('100%'
  33.     .height('100%'
  34.   } 

显示效果:

在ArkUI的ETS中实现【插槽】的功能-鸿蒙HarmonyOS技术社区

通过图片可以看到,builder1,builder2真实位置是在了CompA的slot处。

重点

上面就提到Slot类可以不用创建,因为实现原理是通过ForEach+Builder实现,也可以将Builder通过函数绑定到组件内。

再看一下官方文档中ForEach:

在ArkUI的ETS中实现【插槽】的功能-鸿蒙HarmonyOS技术社区

全部代码供参考

  1. @Entry 
  2. @Component 
  3. struct Index { 
  4.   @Builder builder1(str:string){ 
  5.     Text(str).fontSize(18).fontColor("#f00"
  6.   } 
  7.   @Builder builder2(obj:any){ 
  8.     Column(){ 
  9.       Row(){ 
  10.         Text(obj.title).fontSize(16) 
  11.       } 
  12.       Row(){ 
  13.         QRCode(obj.title).width(100).height(100) 
  14.       }.margin(10) 
  15.     }.margin(10) 
  16.   } 
  17.  slot1:Slot=new Slot(this.builder1) 
  18.  slot2:Slot=new Slot(this.builder2,"slot2"
  19.   build() { 
  20.     Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 
  21.       Column(){ 
  22.          CompA(){ 
  23.            Text("这样是不会显示的").fontSize(24) 
  24.          } 
  25.         CompA({slot:this.slot1}) 
  26.         CompA({slot:this.slot2,data:[{title:"这是第二个插槽"},{title:"http://www.baidu.com"}]}) 
  27.       } 
  28.     } 
  29.     .width('100%'
  30.     .height('100%'
  31.   } 
  32.  
  33. @Component 
  34. struct CompA{ 
  35.   @State text:string="" 
  36.   @State data:string[]=[] 
  37.   @State slot:Slot=new Slot(null
  38.   build(){ 
  39.     Column(){ 
  40.       Column(){ 
  41.         Text("CompA组件内的内容"
  42.         .fontColor("#00F"
  43.         .fontSize(16) 
  44.         .margin(10) 
  45.       } 
  46.       Column(){ 
  47.         Row(){ 
  48.           if(this.slot.name=="default"){ 
  49.             ForEach(["这是默认插槽【default】"], 
  50.               this.slot.builder) 
  51.           } 
  52.           if(this.slot.name=="slot2"){ 
  53.             ForEach(this.data, 
  54.               this.slot.builder) 
  55.           } 
  56.         } 
  57.       } 
  58.     } 
  59.   } 
  60. class Slot{ 
  61.   name:string="default" 
  62.   builder:any 
  63.   constructor (builder:any,name?:string){ 
  64.     name && (this.name=name); 
  65.     this.builder=builder 
  66.   } 

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2022-07-04 16:34:46

流光按钮Stack

2022-10-24 14:49:54

ArkUI心电图组件

2022-11-02 16:06:54

ArkUIETS

2022-07-05 16:13:37

ArkUI-eTS智能晾晒系统

2009-07-09 16:12:53

WeblogicJDBC

2022-08-12 19:13:07

etswifi连接操作

2022-09-05 15:22:27

ArkUIets

2022-02-23 15:07:22

HarmonyOS常用控制ArkUI-eTS

2022-02-23 15:36:46

ArkUI-eTS事件监听鸿蒙

2020-05-25 17:03:47

Vue嵌套插槽开发

2022-07-11 16:26:37

eTS计算鸿蒙

2022-05-26 14:50:15

ArkUITS扩展

2022-01-25 17:05:44

ArkUI_eTS操作系统鸿蒙

2023-10-27 16:15:35

鸿蒙天气服务功能

2022-09-01 21:56:34

KubernetesLinkerd

2023-03-13 15:03:05

鸿蒙ArkUI

2022-07-07 14:01:59

管家服务系统ArkUI eTS

2024-01-02 11:15:46

Linux系统

2023-04-25 08:01:23

JavaQuarkusKubernetes

2022-10-10 14:51:51

ArkUI eTSPieChart组件
点赞
收藏

51CTO技术栈公众号