Modal 模态框
介绍
模态框组件,用于向用户展示提示信息、确认操作等场景,支持标题、内容、取消/确认按钮、关闭前拦截、自定义内容等功能。
引入
typescript
import { TnModal } from "@tuniao/tn-ui";代码演示
基础用法
通过 visible 控制模态框的显示与隐藏,title 设置标题,content 设置内容文本。默认只显示确认按钮。

点我查看代码
typescript
import { TnModal } from "@tuniao/tn-ui";
@Entry
@ComponentV2
struct ModalBasic {
@Local visible: boolean = false;
build() {
Column() {
Button("基础模态框")
.onClick(() => {
this.visible = true;
})
TnModal({
visible: this.visible,
$visible: (visible: boolean) => {
this.visible = visible;
},
title: "提示",
content: "这是一个基础模态框示例",
})
}
}
}无标题模态框
不设置 title 属性时,模态框将不显示标题区域,内容区域会自动调整内边距。

点我查看代码
typescript
TnModal({
visible: this.visible,
$visible: (visible: boolean) => {
this.visible = visible;
},
content: "这是一个没有标题的模态框",
})带取消按钮
通过 showCancel 属性显示取消按钮,同时可以监听 onConfirm 和 onCancel 事件。

点我查看代码
typescript
TnModal({
visible: this.visible,
$visible: (visible: boolean) => {
this.visible = visible;
},
title: "确认操作",
content: "是否确认删除此项目?删除后不可恢复。",
showCancel: true,
onConfirm: () => {
console.info("点击了确认");
},
onCancel: () => {
console.info("点击了取消");
},
})自定义按钮文字
通过 cancelText 和 confirmText 属性自定义取消和确认按钮的文字。

点我查看代码
typescript
TnModal({
visible: this.visible,
$visible: (visible: boolean) => {
this.visible = visible;
},
title: "退出登录",
content: "确定要退出当前账号吗?",
showCancel: true,
cancelText: "再想想",
confirmText: "立即退出",
})自定义按钮颜色
通过 confirmButtonColor 和 cancelButtonColor 属性自定义按钮文字颜色。

点我查看代码
typescript
import { TnModal, getThemeColor, TnUIBaseStyle, TnUIBaseStyleType } from "@tuniao/tn-ui";
import { AppStorageV2 } from "@kit.ArkUI";
import { TnAppStorageKey } from "@tuniao/tn-ui/src/main/ets/common/storage_key";
@Entry
@ComponentV2
struct ModalCustomColor {
@Local visible: boolean = false;
@Local baseStyle: TnUIBaseStyleType = AppStorageV2.connect(TnUIBaseStyle, TnAppStorageKey.BASE_STYLE)!;
build() {
Column() {
Button("自定义按钮颜色")
.onClick(() => {
this.visible = true;
})
TnModal({
visible: this.visible,
$visible: (visible: boolean) => {
this.visible = visible;
},
title: "危险操作",
content: "此操作不可逆,请谨慎确认。",
showCancel: true,
confirmButtonColor: getThemeColor(this.baseStyle, "danger"),
cancelButtonColor: $r("app.color.tn_text_color_secondary"),
})
}
}
}遮罩层设置
通过 overlayCloseable 设置点击遮罩层是否关闭模态框,通过 showOverlay 控制是否显示遮罩层。

点我查看代码
typescript
// 点击遮罩层可关闭
TnModal({
visible: this.visible,
$visible: (visible: boolean) => {
this.visible = visible;
},
title: "提示",
content: "点击遮罩层可关闭此模态框",
overlayCloseable: true,
})
// 不显示遮罩层
TnModal({
visible: this.visibleNoOverlay,
$visible: (visible: boolean) => {
this.visibleNoOverlay = visible;
},
title: "无遮罩",
content: "这个模态框没有遮罩层",
showOverlay: false,
})关闭前拦截
通过 beforeClose 属性设置关闭前的拦截回调。回调接收当前操作类型("cancel" 或 "confirm"),返回 false 或 Promise<false> 可阻止模态框关闭。
点我查看代码
typescript
import { TnModal, TnModalAction } from "@tuniao/tn-ui";
// 同步拦截:只允许确认关闭,取消被拦截
TnModal({
visible: this.visible,
$visible: (visible: boolean) => {
this.visible = visible;
},
title: "拦截关闭",
content: "点击取消将被拦截,只能点击确认关闭。",
showCancel: true,
beforeClose: (action: TnModalAction): boolean => {
if (action === "cancel") {
return false;
}
return true;
},
})
// 异步拦截:模拟异步请求
TnModal({
visible: this.visibleAsync,
$visible: (visible: boolean) => {
this.visibleAsync = visible;
},
title: "异步验证",
content: "点击确认后将模拟异步请求(1秒),成功后关闭。",
showCancel: true,
beforeClose: (action: TnModalAction): Promise<boolean> => {
return new Promise<boolean>((resolve: Function) => {
if (action === "confirm") {
setTimeout(() => {
resolve(true);
}, 1000);
} else {
resolve(true);
}
});
},
})文本对齐方式
通过 titleTextAlign 和 contentTextAlign 属性设置标题和内容的文本对齐方式,支持 "left"、"center"、"right" 三种方式。

点我查看代码
typescript
TnModal({
visible: this.visible,
$visible: (visible: boolean) => {
this.visible = visible;
},
title: "用户协议",
content: "请仔细阅读并同意我们的用户服务协议和隐私政策。继续使用表示您已同意上述条款。",
showCancel: true,
titleTextAlign: "left",
contentTextAlign: "left",
cancelText: "不同意",
confirmText: "同意",
})自定义宽度和圆角
通过 dialogWidth 属性自定义模态框宽度(单位 vp),通过 dialogBorderRadius 属性自定义圆角(单位 vp)。


点我查看代码
typescript
// 自定义宽度
TnModal({
visible: this.visible,
$visible: (visible: boolean) => {
this.visible = visible;
},
title: "宽模态框",
content: "这是一个宽度为 320vp 的模态框",
dialogWidth: 320,
})
// 自定义圆角
TnModal({
visible: this.visibleRadius,
$visible: (visible: boolean) => {
this.visibleRadius = visible;
},
title: "大圆角",
content: "这是一个圆角为 20vp 的模态框",
dialogBorderRadius: 20,
})自定义内容
通过 defaultBuilder 自定义模态框的内容区域,替代默认的 content 文本。

点我查看代码
typescript
import { TnModal, getThemeColor, getFontSizeByKey, TnUIBaseStyle, TnUIBaseStyleType } from "@tuniao/tn-ui";
import { AppStorageV2 } from "@kit.ArkUI";
import { TnAppStorageKey } from "@tuniao/tn-ui/src/main/ets/common/storage_key";
@Entry
@ComponentV2
struct ModalCustomContent {
@Local visible: boolean = false;
@Local baseStyle: TnUIBaseStyleType = AppStorageV2.connect(TnUIBaseStyle, TnAppStorageKey.BASE_STYLE)!;
@Builder
customContent() {
Column({ space: "12vp" }) {
Row({ space: "12vp" }) {
Column() {
Text("128")
.fontSize(getFontSizeByKey(this.baseStyle, "fontSizeXXl"))
.fontColor(getThemeColor(this.baseStyle, "primary"))
.fontWeight(FontWeight.Bold)
Text("积分余额")
.fontSize(getFontSizeByKey(this.baseStyle, "fontSizeSm"))
.fontColor($r("app.color.tn_text_color_secondary"))
}
.layoutWeight(1)
.alignItems(HorizontalAlign.Center)
Column() {
Text("5")
.fontSize(getFontSizeByKey(this.baseStyle, "fontSizeXXl"))
.fontColor(getThemeColor(this.baseStyle, "warning"))
.fontWeight(FontWeight.Bold)
Text("优惠券")
.fontSize(getFontSizeByKey(this.baseStyle, "fontSizeSm"))
.fontColor($r("app.color.tn_text_color_secondary"))
}
.layoutWeight(1)
.alignItems(HorizontalAlign.Center)
}
.width("100%")
Text("是否使用积分兑换优惠券?")
.fontSize(getFontSizeByKey(this.baseStyle, "fontSize"))
.fontColor($r("app.color.tn_text_color_primary"))
.textAlign(TextAlign.Center)
.width("100%")
}
.width("100%")
}
build() {
Column() {
Button("自定义内容")
.onClick(() => {
this.visible = true;
})
TnModal({
visible: this.visible,
$visible: (visible: boolean) => {
this.visible = visible;
},
title: "自定义内容",
showCancel: true,
defaultBuilder: () => {
this.customContent();
},
})
}
}
}自定义底部按钮
通过 footerBuilder 自定义模态框的底部按钮区域,替代默认的取消/确认按钮。

点我查看代码
typescript
import { TnModal, TnButton, TnUIBaseStyle, TnUIBaseStyleType } from "@tuniao/tn-ui";
import { AppStorageV2 } from "@kit.ArkUI";
import { TnAppStorageKey } from "@tuniao/tn-ui/src/main/ets/common/storage_key";
@Entry
@ComponentV2
struct ModalCustomFooter {
@Local visible: boolean = false;
@Local baseStyle: TnUIBaseStyleType = AppStorageV2.connect(TnUIBaseStyle, TnAppStorageKey.BASE_STYLE)!;
@Builder
customFooter() {
Row({ space: "12vp" }) {
TnButton({
content: "取消",
btnSize: "sm",
plain: true,
onBtnClick: () => {
this.visible = false;
},
})
TnButton({
content: "确认提交",
btnSize: "sm",
type: "success",
onBtnClick: () => {
this.visible = false;
},
})
}
.width("100%")
.justifyContent(FlexAlign.Center)
.padding({
left: this.baseStyle.spaceLg,
right: this.baseStyle.spaceLg,
top: this.baseStyle.spaceSm,
bottom: this.baseStyle.spaceLg
})
}
build() {
Column() {
Button("自定义底部按钮")
.onClick(() => {
this.visible = true;
})
TnModal({
visible: this.visible,
$visible: (visible: boolean) => {
this.visible = visible;
},
title: "自定义底部",
content: "底部按钮使用自定义样式",
footerBuilder: () => {
this.customFooter();
},
})
}
}
}API
Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| visible | 是否显示模态框 | boolean | false |
| title | 模态框标题 | string | - |
| content | 模态框内容文本 | string | - |
| showCancel | 是否显示取消按钮 | boolean | false |
| cancelText | 取消按钮文字 | string | "取消" |
| confirmText | 确认按钮文字 | string | "确认" |
| showOverlay | 是否显示遮罩层 | boolean | true |
| overlayCloseable | 点击遮罩层是否关闭 | boolean | false |
| closeOnBackPress | 返回键是否关闭 | boolean | true |
| dialogWidth | 弹窗宽度(单位 vp) | number | 280 |
| dialogBorderRadius | 弹窗圆角(单位 vp),为 0 时使用主题默认圆角 | number | 0 |
| titleTextAlign | 标题文本对齐方式 | "left" | "center" | "right" | "center" |
| contentTextAlign | 内容文本对齐方式 | "left" | "center" | "right" | "center" |
| confirmButtonColor | 确认按钮文字颜色 | ResourceColor | 主题色 |
| cancelButtonColor | 取消按钮文字颜色 | ResourceColor | 主文字色 |
| confirmButtonBold | 确认按钮是否加粗 | boolean | true |
| beforeClose | 关闭前拦截回调,返回 false 可阻止关闭 | (action: TnModalAction) => boolean | Promise<boolean> | - |
BuilderParams
| 参数 | 说明 | 类型 |
|---|---|---|
| defaultBuilder | 自定义内容区域(覆盖 content 文本) | CustomBuilder |
| titleBuilder | 自定义标题区域(覆盖 title 文本) | CustomBuilder |
| footerBuilder | 自定义底部按钮区域(覆盖默认按钮) | CustomBuilder |
Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| onConfirm | 点击确认按钮时触发 | () => void |
| onCancel | 点击取消按钮时触发 | () => void |
| onOpen | 模态框打开时触发 | () => void |
| onClose | 模态框关闭时触发 | () => void |
| $visible | 模态框显示状态变化(双向绑定) | (visible: boolean) => void |
类型定义
TnModalAction
typescript
type TnModalAction = "cancel" | "confirm";TnModalTextAlign
typescript
type TnModalTextAlign = "left" | "center" | "right";TnModalBeforeClose
typescript
type TnModalBeforeClose = (action: TnModalAction) => boolean | Promise<boolean>;