@Builder 与 @BuilderParam区别
·
概述
在 HarmonyOS 应用开发中,经常会遇到"大部分 UI 结构固定,局部需要调用方自定义"的场景。比如一个列表项,左侧固定显示头像和昵称,右侧的按钮则由不同业务决定——有的要"关注",有的要"删除"。如果每种情况都在组件内部写条件分支,组件会越来越臃肿。`@Builder` 和 `@BuilderParam` 就是为了解决这个问题而设计的装饰器。
说明
`@Builder` 用于将一段 UI 声明为可复用的函数,可以在多个地方调用,避免重复代码。`@BuilderParam` 则更进一步——它允许父组件将一段 UI(也是由 `@Builder` 声明的)传入子组件,由子组件在指定位置渲染。这类似于 Vue 的 slot(插槽)或 React 的 render props 模式。
核心区别:
- `@Builder`:本组件把 UI 抽出来复用
- `@BuilderParam`:外部传入 UI,本组件只负责渲染
两者都需要搭配使用,`@BuilderParam` 通常会设置一个默认值(一个 `@Builder` 方法),这样外部不传参时组件也能正常显示。
通过这种方式,组件的各个区域都可以由外部自由定制,而组件本身只需关注结构和布局,业务逻辑完全由调用方决定。
使用实践
① 定义带插槽的组件
@Component
struct MessageItem {
@Prop userName: string = ''
@Prop message: string = ''
@BuilderParam action: () => void = this.defaultAction
@Builder
defaultAction() {
Button('确定').fontSize(12)
}
build() {
Row() {
Circle().width(40).height(40).fill(Color.Gray)
Column() {
Text(this.userName).fontSize(16)
Text(this.message).fontSize(14)
}.margin({ left: 8 })
.layoutWeight(1)
this.action()
}
.padding(12).width('100%')
}
}
② 在不同业务中传入不同的 UI
@Entry
@Component
struct MessageList {
@Builder
followAction() {
Button('关注').backgroundColor(Color.Blue).fontSize(12)
}
@Builder
deleteAction() {
Button('删除').backgroundColor(Color.Red).fontSize(12)
}
build() {
Column() {
MessageItem({ userName: '张三', message: '你好', action: this.followAction })
MessageItem({ userName: '李四', message: '再见', action: this.deleteAction })
// 不带参数走默认:MessageItem({ userName: '默认', message: '默认操作' })
}
}
}
③ 多个插槽的场景
@Component
struct PageContainer {
@BuilderParam header: () => void = this.defaultHeader
@BuilderParam footer: () => void = this.defaultFooter
@Builder defaultHeader() { Text('标题').fontSize(20) }
@Builder defaultFooter() { Button('确定').width('100%') }
build() {
Column() {
this.header()
// 中间内容...
this.footer()
}
}
}
```
使用:`PageContainer({ header: this.myHeader, footer: this.myFooter })`
更多推荐
所有评论(0)