鴻蒙開發(fā)筆記-4-裝飾器之@Builder、@LocalBuilder、@BuilderParam、wrapBuilder

一、核心概念解析

1. @Builder裝飾器:UI復用的基石
  • 定義:將重復的UI邏輯抽象為獨立函數(shù),支持組件內(nèi)或全局復用。
  • 特性
    • 作用域控制:組件內(nèi)(私有)或全局定義。
    • 狀態(tài)訪問:組件內(nèi)可通過this直接訪問狀態(tài)變量。
    • 參數(shù)傳遞:支持按值(默認)或按引用($$范式)傳遞狀態(tài)變量。
  • 示例
    // 組件內(nèi)私有構(gòu)建函數(shù)
    @Component
    struct CounterComponent {
      @State count: number = 0;
      
      @Builder
      CounterUI() {
        Row() {
          Button('+').onClick(() => this.count++);
          Text(`Count: ${this.count}`)
        }
      }
      
      build() {
        Column() { this.CounterUI() }
      }
    }
    

2. @LocalBuilder裝飾器:父子層級維護者
  • 定義:確保子組件在父組件上下文中構(gòu)建,維持組件樹層級關(guān)系。
  • 特性
    • 閉包特性:自動繼承父組件狀態(tài),無需顯式參數(shù)傳遞。
    • 動態(tài)插入:支持在父組件構(gòu)建過程中動態(tài)插入同層級UI片段。
  • 示例
    @Component
    struct ParentComponent {
      @State showFooter: boolean = false;
      
      @LocalBuilder
      dynamicFooter() {
        if (this.showFooter) {
          Text("動態(tài)底部內(nèi)容").fontSize(18)
        }
      }
      
      build() {
        Column() {
          Text("主體內(nèi)容")
          this.dynamicFooter()
        }
      }
    }
    

3. @BuilderParam裝飾器:動態(tài)插槽實現(xiàn)者
  • 定義:用于定義組件插槽,允許父組件向子組件注入自定義UI邏輯。
  • 特性
    • 類型安全:需嚴格匹配目標@Builder函數(shù)簽名。
    • 初始化方式:支持參數(shù)傳遞、尾隨閉包或箭頭函數(shù)。
  • 示例
    // 子組件定義插槽
    @Component
    struct CardComponent {
      @BuilderParam content: () => void;
      
      build() {
        Column() { this.content() }
      }
    }
    
    // 父組件注入內(nèi)容
    @Entry
    @Component
    struct App {
      @Builder
      cardContent() {
        Image($r('app.media.logo')).width(100)
      }
      
      build() {
        CardComponent({ content: this.cardContent })
      }
    }
    

4. wrapBuilder技術(shù):構(gòu)建器增強器
  • 定義:用于封裝全局@Builder函數(shù)為可存儲對象,支持動態(tài)調(diào)用。
  • 特性
    • 對象化封裝:將全局構(gòu)建函數(shù)轉(zhuǎn)為WrappedBuilder對象。
    • 動態(tài)調(diào)用:支持存入數(shù)組并通過ForEach動態(tài)渲染。
  • 示例
    // 封裝全局構(gòu)建函數(shù)
    const wrappedBuilders = [
      wrapBuilder(HeaderBuilder),
      wrapBuilder(FooterBuilder)
    ]
    
    @Entry
    @Component
    struct MainPage {
      build() {
        Column() {
          ForEach(wrappedBuilders, (builder) => {
            builder.builder("動態(tài)標題")
          })
        }
      }
    }
    

二、四者對比分析表

維度 @Builder @LocalBuilder @BuilderParam wrapBuilder
核心功能 UI復用 維護父子層級關(guān)系 動態(tài)插槽 構(gòu)建器對象化封裝
作用域 組件內(nèi)/全局 組件內(nèi) 跨組件 全局構(gòu)建函數(shù)專用
狀態(tài)訪問 直接訪問組件狀態(tài) 繼承父組件狀態(tài) 依賴參數(shù)傳遞 不直接處理狀態(tài)
參數(shù)傳遞 值/引用傳遞 自動繼承上下文 嚴格類型匹配 支持值/引用類型參數(shù)
典型場景 通用UI模板 動態(tài)列表項/條件渲染 可配置組件 動態(tài)構(gòu)建器數(shù)組調(diào)用
初始化限制 必須組件內(nèi)定義 需用@Builder函數(shù)初始化 僅支持全局@Builder封裝

三、進階應用模式

1. 組合式構(gòu)建
// 全局構(gòu)建函數(shù) + 構(gòu)建器增強
function ThemedButton(builder: () => Button) {
  return () => {
    const button = builder();
    button.backgroundColor(Color.Primary);
    return button;
  };
}

@Builder
function DefaultButton(text: string) {
  return ThemedButton(() => Button(text));
}
2. 層級化動態(tài)渲染
@Component
struct NestedComponent {
  @LocalBuilder
  renderItem(item: string) {
    Text(item).fontSize(18);
  }
  
  build() {
    Column() {
      ForEach(this.items, (item) => this.renderItem(item));
    }
  }
}
3. 插槽與狀態(tài)聯(lián)動
@Component
struct StatefulCard {
  @State message: string = "初始消息";
  @BuilderParam content: (message: string) => void;
  
  build() {
    Column() {
      this.content(this.message);
      Button("更新消息").onClick(() => this.message = "新消息");
    }
  }
}

四、總結(jié)

  • @Builder:適用于模塊化UI復用,通過參數(shù)傳遞策略平衡靈活性與性能。
  • @LocalBuilder:解決父子組件層級關(guān)系問題,適合動態(tài)內(nèi)容插入。
  • @BuilderParam:實現(xiàn)組件插槽機制,提升UI組合能力。
  • wrapBuilder:動態(tài)構(gòu)建器調(diào)用的終極方案,特別適合可視化搭建場景。

我是今陽,如果想要進階和了解更多的干貨,歡迎關(guān)注wxgzh “今陽說” 接收我的最新文章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容