一、自定义弹窗
@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用下面这种方式,预览会报错 ??? 不明白
二、二次封装自定义弹窗组件
@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: '我是来自最顶层的文字',
})
}
}
}