核心是使用 CustomDialog 
但是官方示例在代码耦合上会对新手产生误解, 这里就来封装一下,直接上核心代码
BuiCustomDialog

/**
 * 作为全局弹窗组件封装 内容完全由外部slot定义
 *
 */
@Builder function empty(){}
@CustomDialog
export default struct BuiCustomDialog {
  controller?:CustomDialogController
  @BuilderParam slot:()=>void =empty
  build(){
    this.slot()
  }
}

是的,核心代码就这么多,主要作用就是暴露slot,使得弹窗内容外部可用
 

下面是第二层封装,作为系统内弹窗的代理层
 

import BuiCustomDialog from './BuiCustomDialog';

@Builder function empty(){}
/**
 * 用于代理dialog的打开和关闭
 */
export interface BuiPopupController{
  open:()=>void
  close:()=>void
}
/**
 * 作为所有弹窗类的基础组件
 * 以此为拓展,可以 开发 选择城市 选择商户 选择商品 或者 confirm dialog 等  等弹窗
 */
@Component
export default struct BuiPopup  {

  controller:BuiPopupController|null=null
  /**
   * 弹窗位置
   */
  alignment:DialogAlignment=DialogAlignment.Bottom;
  /**
   * 上下 偏移量 负数则往上
   */
  offsetY:number=0
  /**
   * 点击遮罩层是否关闭弹窗
   */
  clickMaskClose:boolean=true

  maskColor:ResourceColor = "rgba(0,0,0,0.1)"
  /**
   * 最大高度
   */
  maxHeight:Length = 800

  @BuilderParam slot:()=>void =empty



  private  dialogController: CustomDialogController  
  build(){

  }
  @Builder buildContent(){
      Column(){
        this.slot();
      } .width('100%').zIndex(1)
    .constraintSize({ maxHeight: this.getMaxHeight() })
  }

  aboutToAppear(){
    //修正,这里要在这里初始化,否则 this.clickMaskClose 不能响应外部变更
       this.dialogController = new CustomDialogController({
    builder: BuiCustomDialog({
      slot:()=>{
        this.buildContent();
      }
    }) ,
    alignment:this.alignment,
    offset: { dx: 0, dy: this.offsetY },
    maskColor:this.maskColor,
    autoCancel: this.clickMaskClose,
    //完全依靠外部样式控制,否则会有宽度限制和默认圆角, 这里需要的就是要自己控制样式
    customStyle:true
  });
    if(this.controller) {
      this.controller.open = () => {
        this.dialogController.open();
      }
      this.controller.close = () => {
        this.dialogController.close();
      }

    }
  }

  getMaxHeight():Length{
    return this.maxHeight||'100%';
  }


}

这一层主要是对CustomDialogController 的参数进行设置和代理,暴露出去,方便进行下一层级的功能使用 

最后附上简单使用,这个使用逻辑,也是下一层级代理的使用方法

import EventHub from '../../common/EventHub';
import BuiPopup, { BuiPopupController } from '../bui/BuiPopup';

@Component
export default struct BuiPopupDemo {
  @State visible: boolean = false;

  dialogController:BuiPopupController={} as BuiPopupController

  build() {
    Column() {
      this.buildContent();
    }
  }

  @Builder
  buildContent() {
    Grid(){
      GridItem() {
        Button("关闭弹窗").width(100).onClick(() => {
          this.dialogController.close()
        });
      }
      GridItem() {
        Button("打开示例弹窗").width(100).onClick(() => {
          this.dialogController.open();
        });
      }

    }


    BuiPopup({
        controller: this.dialogController ,
        slot:()=>{
          this.buildPopContent();
        }
    });


  }

  @Builder
  buildPopContent() {
    Column() {
      Text("我可以是任意内容")
    }.backgroundColor("white").width("100%")
    .borderRadius({
      topLeft:16,
      topRight:16
    }).constraintSize({minHeight:200})


  }
}

 

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐