✅ 背景说明

在企业级应用中,弹窗(Dialog)用途极广,如:

  • 操作确认(如删除确认)

  • 信息提示(如错误信息)

  • 自定义表单嵌入(如添加备注)

但实际开发中,重复弹窗逻辑缺少插槽自定义能力状态耦合复杂等问题频发。

本篇将封装一个灵活强大、具插槽能力与统一 API 回调机制DialogBox 组件,适用于各类项目中的通用交互。


🧱 一、组件功能目标

  • 支持标题、内容、按钮文本配置;

  • 支持 confirm/cancel 回调函数;

  • 支持内容插槽(slot);

  • 支持父组件控制显示;

  • 支持默认布局,也支持完全自定义内容。


📦 二、组件结构设计

@Component
struct DialogBox {
  @Prop title: string = '';
  @Prop message: string = '';
  @Prop confirmText: string = '确定';
  @Prop cancelText: string = '取消';
  @Prop show: boolean = false;
  @Prop onConfirm: () => void = () => {};
  @Prop onCancel: () => void = () => {};
  @Slot content?: () => void; // 可插入内容
}

🧩 三、组件 UI 构建

build() {
  if (!this.show) return;

  Column()
    .position({ x: 0, y: 0 })
    .width('100%')
    .height('100%')
    .backgroundColor('#00000050') // 半透明背景
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Center) {
      Column({ space: 10 })
        .width('80%')
        .padding(20)
        .backgroundColor('#fff')
        .borderRadius(12) {
          if (this.title) {
            Text(this.title).fontSize(18).fontWeight(FontWeight.Bold)
          }

          if (this.content) {
            this.content!()
          } else {
            Text(this.message).fontSize(14)
          }

          Row({ space: 10 }) {
            Button(this.cancelText).onClick(() => this.onCancel())
            Button(this.confirmText).onClick(() => this.onConfirm())
          }
        }
    }
}

🧪 四、父组件使用示例(简洁模式)

@Component
struct DialogDemo {
  @State showDialog: boolean = false;

  build() {
    Column({ space: 10 }) {
      Button('弹出提示').onClick(() => this.showDialog = true)

      DialogBox({
        title: '删除确认',
        message: '是否确认删除此数据?',
        show: this.showDialog,
        onConfirm: () => {
          this.showDialog = false;
          console.info('已确认删除');
        },
        onCancel: () => this.showDialog = false
      })
    }.padding(20)
  }
}

🎨 五、父组件使用示例(自定义插槽)

DialogBox({
  title: '输入备注',
  show: this.showDialog,
  onConfirm: () => { this.showDialog = false; },
  onCancel: () => this.showDialog = false
}) {
  TextInput({ placeholder: '请输入备注', text: this.remark })
    .onChange(v => this.remark = v)
}

⚠️ 六、易错点与处理建议

问题 原因 解决方案
弹窗无法控制关闭 show 状态未外部绑定 使用 @Prop show,由父组件控制显示
多个弹窗共用状态 未隔离每个弹窗的状态作用域 可封装 DialogService 或用组件 ID 区分
插槽内容失效 插槽未定义或未渲染 @Slot 判断是否存在再渲染

🚀 七、拓展方向建议

  • 支持 Esc 键退出、点击遮罩关闭;

  • 支持插入 Footer、Header 插槽;

  • 可传入图标或动画组件;

  • 可构建 DialogService 全局调用(单例化 + Promise 化);

  • 支持多层嵌套弹窗管理栈(如 ElDialog 的 stack 机制);


✅ 小结

本篇封装了一个支持插槽、回调、布局灵活的 DialogBox 通用弹窗组件,实现了企业级项目中高频弹窗需求的一次性解决方案,具有很强的复用性与扩展性。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐