自学鸿蒙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: '我是来自最顶层的文字',

      })
    }
  }
}
相关推荐
踏雪Vernon2 小时前
[OpenHarmony5.0][Docker][环境]OpenHarmony5.0 Docker编译环境镜像下载以及使用方式
linux·docker·容器·harmonyos
Andy醒6 小时前
HarmonyOS . 沉浸状态栏使用
harmonyos·鸿蒙
yuwinter6 小时前
鸿蒙HarmonyOS学习笔记(2)
笔记·学习·harmonyos
ZZZCY20037 小时前
华为ENSP--IP编址及静态路由配置
网络·华为
jikuaidi6yuan8 小时前
鸿蒙系统(HarmonyOS)分布式任务调度
分布式·华为·harmonyos
智慧化智能化数字化方案14 小时前
华为IPD流程管理体系L1至L5最佳实践-解读
大数据·华为
ZZZCY200315 小时前
华为VER系统及CLI命令熟悉
华为
SameX16 小时前
HarmonyOS Next 安全生态构建与展望
前端·harmonyos
SameX16 小时前
HarmonyOS Next 打造智能家居安全系统实战
harmonyos