<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ArkTS @BuilderParam 使用总结</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);
color: #333;
min-height: 100vh;
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
}
.container {
max-width: 1200px;
width: 100%;
display: flex;
flex-direction: column;
gap: 30px;
}
header {
background-color: rgba(255, 255, 255, 0.9);
padding: 30px;
border-radius: 15px;
text-align: center;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
margin-bottom: 20px;
}
h1 {
color: #2c3e50;
margin-bottom: 15px;
font-size: 2.5rem;
}
.subtitle {
color: #7f8c8d;
font-size: 1.3rem;
margin-bottom: 20px;
}
.content {
display: flex;
gap: 30px;
flex-wrap: wrap;
}
.card {
flex: 1;
min-width: 300px;
background: white;
border-radius: 15px;
overflow: hidden;
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.12);
transition: transform 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
}
.card-header {
background: #3498db;
color: white;
padding: 20px;
font-weight: bold;
font-size: 1.3rem;
display: flex;
align-items: center;
gap: 10px;
}
.card-body {
padding: 25px;
}
.card-body h3 {
color: #2c3e50;
margin-bottom: 15px;
border-bottom: 2px solid #eee;
padding-bottom: 10px;
}
pre {
background: #f8f9fa;
padding: 18px;
border-radius: 8px;
overflow-x: auto;
margin: 18px 0;
line-height: 1.5;
font-size: 0.95rem;
border-left: 4px solid #3498db;
}
code {
font-family: 'Fira Code', monospace;
}
.explanation {
margin-top: 18px;
padding: 18px;
background: #f1f8ff;
border-radius: 8px;
border-left: 4px solid #3498db;
}
.key-point {
font-weight: bold;
color: #2980b9;
}
.footer {
margin-top: 40px;
text-align: center;
color: white;
font-size: 1rem;
padding: 20px;
background: rgba(0, 0, 0, 0.2);
border-radius: 10px;
width: 100%;
}
.note {
background: #fff3cd;
border-left: 4px solid #ffc107;
padding: 18px;
margin: 18px 0;
border-radius: 8px;
}
.icon {
font-size: 1.5rem;
}
@media (max-width: 768px) {
.content {
flex-direction: column;
}
header {
padding: 20px;
}
h1 {
font-size: 2rem;
}
}
.summary {
background: white;
border-radius: 15px;
padding: 30px;
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.12);
}
.summary h2 {
color: #2c3e50;
margin-bottom: 20px;
border-bottom: 2px solid #eee;
padding-bottom: 10px;
}
.summary ul {
list-style-type: none;
padding: 0;
}
.summary li {
padding: 12px;
margin-bottom: 12px;
background: #f8f9fa;
border-radius: 8px;
border-left: 4px solid #3498db;
display: flex;
align-items: center;
gap: 10px;
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>ArkTS @BuilderParam 使用总结</h1>
<p class="subtitle">全面掌握@BuilderParam的各种用法和场景</p>
</header>
<div class="content">
<div class="card">
<div class="card-header">
<i class="fas fa-code icon"></i>
<span>基础用法</span>
</div>
<div class="card-body">
<h3>初始化@BuilderParam</h3>
<pre><code>@Builder
function overBuilder() {
}
@Component
struct Child {
@Builder
doNothingBuilder() {
}
// 使用自定义组件的自定义构建函数初始化@BuilderParam
@BuilderParam customBuilderParam: () => void = this.doNothingBuilder;
// 使用全局自定义构建函数初始化@BuilderParam
@BuilderParam customOverBuilderParam: () => void = overBuilder;
build() {
}
}</code></pre>
<div class="explanation">
<p><span class="key-point">说明:</span>@BuilderParam可以使用组件内部的@Builder函数或全局@Builder函数进行初始化。</p>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<i class="fas fa-exchange-alt icon"></i>
<span>父子组件传参</span>
</div>
<div class="card-body">
<h3>父组件传递@Builder给子组件</h3>
<pre><code>@Component
struct Child {
@BuilderParam customBuilderParam: () => void;
build() {
Column() {
this.customBuilderParam()
}
}
}
@Entry
@Component
struct Parent {
@Builder
componentBuilder() {
Text(`Parent builder `)
}
build() {
Column() {
Child({ customBuilderParam: this.componentBuilder })
}
}
}</code></pre>
<div class="explanation">
<p><span class="key-point">说明:</span>父组件可以将自己的@Builder函数传递给子组件的@BuilderParam,实现灵活的UI构建。</p>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<i class="fas fa-project-diagram icon"></i>
<span>this指向问题</span>
</div>
<div class="card-body">
<h3>处理@Builder中的this指向</h3>
<pre><code>@Entry
@Component
struct Parent {
label: string = 'Parent';
@Builder
componentBuilder() {
Text(`${this.label}`)
}
build() {
Column() {
Child({
// this指向子组件
customBuilderParam: this.componentBuilder,
// 使用箭头函数,this指向父组件
customChangeThisBuilderParam: (): void => {
this.componentBuilder()
}
})
}
}
}</code></pre>
<div class="explanation">
<p><span class="key-point">说明:</span>直接传递@Builder函数时,this指向接收组件;使用箭头函数包装时,this指向定义时的组件。</p>
</div>
</div>
</div>
</div>
<div class="content">
<div class="card">
<div class="card-header">
<i class="fas fa-cogs icon"></i>
<span>参数传递</span>
</div>
<div class="card-body">
<h3>带参数的@Builder函数</h3>
<pre><code>class Tmp {
label: string = '';
}
@Builder
function overBuilder($$: Tmp) {
Text($$.label)
.width(400)
.height(50)
}
@Component
struct Child {
// 有参数类型,指向的overBuilder也是有参数类型的方法
@BuilderParam customOverBuilderParam: ($$: Tmp) => void = overBuilder;
build() {
Column() {
this.customOverBuilderParam({ label: 'global Builder label' })
}
}
}</code></pre>
<div class="explanation">
<p><span class="key-point">说明:</span>@BuilderParam可以定义参数类型,并与相应签名的@Builder函数配合使用。</p>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<i class="fas fa-code-branch icon"></i>
<span>尾随闭包</span>
</div>
<div class="card-body">
<h3>使用尾随闭包初始化@BuilderParam</h3>
<pre><code>@Component
struct CustomContainer {
@Prop header: string = '';
@BuilderParam closer: () => void;
build() {
Column() {
Text(this.header)
.fontSize(30)
this.closer()
}
}
}
@Entry
@Component
struct CustomContainerUser {
@State text: string = 'header';
build() {
Column() {
// 使用尾随闭包{}初始化@BuilderParam
CustomContainer({ header: this.text }) {
Column() {
Text('尾随闭包内容')
}
}
}
}
}</code></pre>
<div class="explanation">
<p><span class="key-point">说明:</span>通过在组件后紧跟大括号"{}"形成尾随闭包,可以初始化子组件的@BuilderParam。</p>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<i class="fas fa-mobile-alt icon"></i>
<span>页面级使用</span>
</div>
<div class="card-body">
<h3>在页面组件中使用</h3>
<pre><code>@ComponentV2
struct ChildPage {
@Require @Param message: string = '';
@BuilderParam customBuilderParam: () => void;
build() {
Column() {
Text(this.message)
.fontSize(30)
this.customBuilderParam()
}
}
}
@Entry
@ComponentV2
struct ParentPage {
@Local label: string = 'Parent Page';
@Builder
componentBuilder() {
Text(`局部 Builder: ${this.label}`)
}
build() {
Column() {
ChildPage({ message: this.label }) {
// 使用尾随闭包初始化@BuilderParam
Column() {
this.componentBuilder();
}
}
}
}
}</code></pre>
<div class="explanation">
<p><span class="key-point">说明:</span>@BuilderParam在页面级组件中的使用方式类似,支持局部和全局@Builder函数。</p>
</div>
</div>
</div>
</div>
<div class="summary">
<h2><i class="fas fa-check-circle"></i> @BuilderParam 使用要点总结</h2>
<ul>
<li><i class="fas fa-arrow-right"></i> <strong>初始化</strong>:可以使用组件内部的@Builder函数或全局@Builder函数初始化</li>
<li><i class="fas fa-arrow-right"></i> <strong>传递方式</strong>:父组件可以通过属性传递@Builder函数给子组件的@BuilderParam</li>
<li><i class="fas fa-arrow-right"></i> <strong>this指向</strong>:直接传递@Builder函数时,this指向接收组件;使用箭头函数时,this指向定义时的组件</li>
<li><i class="fas fa-arrow-right"></i> <strong>参数传递</strong>:@BuilderParam可以定义参数类型,需要与相应签名的@Builder函数配合使用</li>
<li><i class="fas fa-arrow-right"></i> <strong>尾随闭包</strong>:通过在组件后紧跟大括号"{}"形成尾随闭包,可以初始化子组件的@BuilderParam</li>
<li><i class="fas fa-arrow-right"></i> <strong>使用场景</strong>:适用于需要动态定制组件部分UI的场景,提高组件的灵活性和复用性</li>
</ul>
<div class="note">
<p><strong>最佳实践建议:</strong></p>
<p>1. 明确@BuilderParam的函数签名,避免类型不匹配</p>
<p>2. 注意this的指向问题,根据需要选择直接传递或使用箭头函数</p>
<p>3. 对于复杂的UI构建,考虑使用带参数的@Builder函数</p>
<p>4. 在组件文档中明确说明@BuilderParam的预期用途和参数要求</p>
</div>
</div>
<div class="footer">
<p>ArkTS @BuilderParam 使用总结 | 开发者指南与最佳实践</p>
</div>
</div>
</body>
</html>