一、自定义弹窗
@CustomDialog
struct CustomDialogBuilder {controller: CustomDialogController = new CustomDialogController({ // 注意写法builder: CustomDialogBuilder({})})// controller: CustomDialogController // 这种预览会报错cancel?: () => voidconfirm?: () => voidtext?: stringbuild() {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不会触发cancelconsole.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用下面这种方式,预览会报错 ??? 不明白
二、二次封装自定义弹窗组件
@CustomDialog
struct CustomDialogBuilder {@Link visible: booleancontroller: CustomDialogController = new CustomDialogController({ // 注意写法builder: CustomDialogBuilder({visible: $visible})})// controller: CustomDialogController // 这种预览会报错cancel?: () => voidconfirm?: () => voidtext?: stringbuild() {Column() {Text(this.text).padding(20)Flex({ justifyContent: FlexAlign.SpaceAround }) {Button('取消').buttonStyle(ButtonStyleMode.TEXTUAL).onClick(() => {this.visible = falsethis.controller.close() // 关闭弹窗if (this.cancel) {this.cancel()}})Button('确定').buttonStyle(ButtonStyleMode.TEXTUAL).onClick(() => {this.visible = falseif (this.confirm) {this.confirm()}})}.padding(10)}}
}// 二次封装
@Component
struct Dialog {@Watch('onChange') @Link visible: boolean // 必须在@link前,否则报错cancel?: () => voidconfirm?: () => voidtext?: stringprivate 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 = falseonCancel() {console.log('我是来自最顶层的onCancel')}onConfirm() {console.log('我是来自最顶层的onConfirm')}build() {Column() {Button('点击我可以获取一个自定义弹窗').onClick(() => {this.visible = !this.visibleconsole.log(this.visible+'')})Dialog({visible: this.visible,cancel: () => {console.log('我是来自最顶层的oncancel')},confirm: () => {console.log('我是来自最顶层的onConfirm')},text: '我是来自最顶层的文字',})}}
}