自学鸿蒙HarmonyOS的ArkTS语言<九>自定义弹窗组件CustomDialog及二次封装自定义弹窗

一、自定义弹窗
java 复制代码
@CustomDialog
struct CustomDialogBuilder {
  controller: CustomDialogController = new CustomDialogController({ // 注意写法
    builder: CustomDialogBuilder({})
  })

  // controller: CustomDialogController // 这种预览会报错
  cancel?: () => void
  confirm?: () => void
  text?: string

  build() {
    Column() {
      Text(this.text)
        .padding(20)
      Flex({ justifyContent: FlexAlign.SpaceAround }) {
        Button('取消')
          .buttonStyle(ButtonStyleMode.TEXTUAL)
          .onClick(() => {
            this.controller.close() // 关闭弹窗
            if (this.cancel) {
              this.cancel()
            }
          })
        Button('确定')
          .buttonStyle(ButtonStyleMode.TEXTUAL)
          .onClick(() => {
            if (this.confirm) {
              this.confirm()
            }
        })
      }.padding(10)

    }
  }
}

@Entry
@Component
struct Index6 {
  @State text: string = '我是来自父组件的内容'
  dialogController: CustomDialogController | null = new CustomDialogController({
    // builder->自定义弹窗内容构造器
    builder: CustomDialogBuilder({
      cancel: () => { this.onCancel() }, // 不能写成 () => this.onCancel()
      confirm: () => { this.onAccept() },
      text: this.text
    }),
    alignment: DialogAlignment.Center,
    autoCancel: true,
    cancel: () => {
      console.log('点击遮罩层')
    },
    onWillDismiss: (res: DismissDialogAction) => { // 有了onWillDismiss不会触发cancel
      console.log('onWillDismiss:', JSON.stringify(res))
    }
    // ... 还可以设置backgroundColor, cornerRadius等
  })

  // 在自定义组件即将析构销毁时将dialogController置空
  aboutToDisappear() {
    this.dialogController = null // 将dialogController置空
  }

  onCancel() {
    console.log('我是父组件中的onCancel')
  }

  onAccept() {
    console.log('我是父组件中的onAccept')
  }

  build() {
    Button('点击我可以获取一个自定义弹窗')
      .onClick(() => {
        if (this.dialogController !== null) { // dialogController有null类型,必须判断否则报错
          this.text = '我是来自父组件中的内容2'
          this.dialogController.open() // 打开弹窗
        }
      })
  }
}

注意点:

1、自定义弹窗用 @CustomDialog 装饰

2、和普通组件不一样的是自定义弹窗是通过实例化CustomDialogController类显示的,其内容是builder参数(自定义弹窗内容构造器)

3、构造器里面传参的写法

4、自定义函数中controller用下面这种方式,预览会报错 ??? 不明白

二、二次封装自定义弹窗组件
java 复制代码
@CustomDialog
struct CustomDialogBuilder {
  @Link visible: boolean
  controller: CustomDialogController = new CustomDialogController({ // 注意写法
    builder: CustomDialogBuilder({
      visible: $visible
    })
  })

  // controller: CustomDialogController // 这种预览会报错
  cancel?: () => void
  confirm?: () => void
  text?: string

  build() {
    Column() {
      Text(this.text)
        .padding(20)
      Flex({ justifyContent: FlexAlign.SpaceAround }) {
        Button('取消')
          .buttonStyle(ButtonStyleMode.TEXTUAL)
          .onClick(() => {
            this.visible = false
            this.controller.close() // 关闭弹窗
            if (this.cancel) {
              this.cancel()
            }
          })
        Button('确定')
          .buttonStyle(ButtonStyleMode.TEXTUAL)
          .onClick(() => {
            this.visible = false
            if (this.confirm) {
              this.confirm()
            }
        })
      }.padding(10)

    }
  }
}

// 二次封装
@Component
struct Dialog {
  @Watch('onChange') @Link visible: boolean // 必须在@link前,否则报错
  cancel?: () => void
  confirm?: () => void
  text?: string

  private controller = new CustomDialogController({
    builder: CustomDialogBuilder({
      cancel: this.cancel,
      confirm: this.confirm,
      visible: $visible,
      text: this.text
    }),
    alignment: DialogAlignment.Center,
    autoCancel: true,
    cancel: () => {
      console.log('点击遮罩层')
    },
    onWillDismiss: (res: DismissDialogAction) => {
      console.log('onWillDismiss:', JSON.stringify(res))
    }
  })

  onChange() {
    console.log('监听visible:', this.visible)
    if (this.visible) {
      this.controller.open()
    } else {
      this.controller.close()
    }
  }

  build() {
  }
}

@Entry
@Component
struct Index6 {
  @State visible: boolean = false

  onCancel() {
    console.log('我是来自最顶层的onCancel')
  }

  onConfirm() {
    console.log('我是来自最顶层的onConfirm')
  }

  build() {
    Column() {
      Button('点击我可以获取一个自定义弹窗')
        .onClick(() => {
          this.visible = !this.visible
          console.log(this.visible+'')
        })

      Dialog({
        visible: this.visible,
        cancel: () => {
          console.log('我是来自最顶层的oncancel')
        },
        confirm: () => {
          console.log('我是来自最顶层的onConfirm')
        },
        text: '我是来自最顶层的文字',

      })
    }
  }
}
相关推荐
程序猿追4 分钟前
HarmonyOS 6.0 NEXT:基于 Map Kit 实现一款“手绘路线”骑行导航应用
华为·harmonyos
轻口味1 小时前
HarmonyOS 6.1 全栈实战录 - 08 视讯巅峰:Media Kit 视频缩略图批量提取与 HDR 渲染链路实战
华为·音视频·harmonyos
想你依然心痛2 小时前
HarmonyOS 6(API 23)实战:基于悬浮导航、沉浸光感与HMAF的“医智助手“——医疗影像AI智能体辅助诊断平台
人工智能·华为·harmonyos
nashane2 小时前
HarmonyOS 6学习:卡片组件圆角白边问题的诊断与修复实战
人工智能·pytorch·深度学习·harmonyos
川石课堂软件测试2 小时前
接口测试常见面试题及答案
python·网络协议·mysql·华为·单元测试·prometheus·harmonyos
痕忆丶2 小时前
openharmony北向开发基础之OpenHarmony签名机制详解
linux·harmonyos
not coder3 小时前
HarmonyOS NEXT 原生OFD阅读库实测:纯ArkTS无依赖,完美适配电子发票与政务公文开发
华为·harmonyos·鸿蒙·ofd·政务
richard_yuu3 小时前
鸿蒙隐私级树洞实战|ArkTS 实现写完即清空、零内存残留、零隐私留存
华为·harmonyos
三声三视3 小时前
Electron 在鸿蒙 PC 上启动慢?我把冷启动从 7 秒压到 1.5 秒的完整记录
electron·harmonyos·桌面应用
leon_teacher4 小时前
HarmonyOS 6 古诗学习宝实战:基于 Preferences 实现错题本自动派生与题级去重系统
学习·华为·harmonyos