Modal
17:06Description
A centered modal built on ux-popup, with a configurable title, content text, and confirm/cancel buttons (text and colors). Confirm or cancel closes it automatically by default; with async-close enabled, tapping confirm only puts the button into a loading state and the closing moment is left to the caller.
Compatibility
| Platform | Support |
|---|---|
| App | ✅ Supported |
| H5 | ✅ Supported |
| WeChat Mini Program | ✅ Supported |
Examples
Basic Usage
Tap the button to show a modal with customizable title, content and buttons.
View source
vue
<template>
<ux-button type="primary" @click="show = true">打开弹窗</ux-button>
<ux-modal
v-model="show"
content="这是弹窗内容"
:show-cancel-button="true"
@confirm="onConfirm"
@cancel="onCancel"
/>
</template>
<script setup lang="uts">
const show = ref<boolean>(false);
const onConfirm = () => {
show.value = false;
uni.showToast({ title: '点击了确定', icon: 'none' });
};
const onCancel = () => {
show.value = false;
uni.showToast({ title: '点击了取消', icon: 'none' });
};
</script>Custom Content
Customize the title, content and confirm/cancel button text.
View source
vue
<template>
<ux-button type="success" @click="show = true">打开弹窗</ux-button>
<ux-modal
v-model="show"
title="自定义弹窗"
content="自定义标题与按钮文案的弹窗"
:show-cancel-button="true"
confirm-text="好的"
cancel-text="不了"
@confirm="onConfirm"
/>
</template>
<script setup lang="uts">
const show = ref<boolean>(false);
const onConfirm = () => {
show.value = false;
uni.showToast({ title: '点击了确定', icon: 'none' });
};
</script>Async Close
With async-close=true, the confirm button shows a loading state and closing is controlled externally.
View source
vue
<template>
<ux-button type="warning" @click="show = true">打开弹窗</ux-button>
<text v-if="loading" class="tip">正在处理...</text>
<ux-modal
v-model="show"
title="异步关闭"
content="点击确定后 2 秒自动关闭"
:async-close="true"
:show-cancel-button="true"
@confirm="onConfirm"
/>
</template>
<script setup lang="uts">
const show = ref<boolean>(false);
const loading = ref<boolean>(false);
const onConfirm = () => {
loading.value = true;
setTimeout(() => {
show.value = false;
loading.value = false;
}, 2000);
};
</script>
<style scoped>
.tip {
font-size: 12px;
color: #909399;
margin-top: 6px;
}
</style>API
Props
| Property | Description | Type | Default | Version |
|---|---|---|---|---|
customStyle | Custom root element style | string | UTSJSONObject | - | - |
customClass | Custom root element style class | string | '' | - |
modelValue | Whether to show the modal | boolean | false | - |
zIndex | z-index level | string | number | '' | - |
title | Title | string | '' | - |
width | Modal width | string | number | 300 | - |
content | Modal content | string | '' | - |
showTitle | Whether to show the title | boolean | true | - |
showConfirmButton | Whether to show the confirm button | boolean | true | - |
showCancelButton | Whether to show the cancel button | boolean | false | - |
confirmText | Confirm button text | string | '' | - |
cancelText | Cancel button text | string | '' | - |
confirmColor | Confirm button color | string | '' | - |
cancelColor | Cancel button text color | string | '' | - |
borderRadius | Corner radius | string | number | 8 | - |
titleStyle | Title style | UTSJSONObject | - | - |
contentStyle | Content style | UTSJSONObject | - | - |
cancelStyle | Cancel button style | UTSJSONObject | - | - |
confirmStyle | Confirm button style | UTSJSONObject | - | - |
zoom | Whether to enable the zoom effect | boolean | true | - |
asyncClose | Whether to close asynchronously; only applies to the confirm button | boolean | false | - |
maskCloseAble | Whether tapping the mask may close the modal | boolean | false | - |
marginTop | Vertical offset: positive moves down, negative moves up (pass a negative value to dodge the keyboard); forwarded to ux-popup's margin-top | string | number | 0 | - |
global | Whether to act as a global root modal (usually placed in App.vue for useModal()) | boolean | false | - |
page | Whether to act as a page-level modal (usually placed in a page for useModal({ page: true })) | boolean | string | false | - |
Events
| Event | Description | Params | Version |
|---|---|---|---|
confirm | Confirm button tapped | - | - |
cancel | Cancel button tapped | - | - |
Slots
| Slot | Description | Version |
|---|---|---|
default | Custom modal content area; when present it replaces the content text | - |
confirm-button | Custom confirm-button content; when present it replaces the loading icon and confirm text | - |
Notes
async-closeonly applies to the confirm button: tapping confirm puts the button into a loading state and the modal does not close itself; setv-modelback tofalseonce your business logic finishes. Reopening resets the loading state.- When not in async mode, tapping confirm or cancel immediately sets the visible state to
false(the modal closes automatically), so no manual closing is needed. mask-close-abledefaults tofalse, so tapping the mask does not close the modal by default; passtrueexplicitly to enable it.confirm/cancelcarry no payload; async work and other business logic are entirely up to the caller.- Leaving the title, confirm or cancel text empty falls back to the component's built-in i18n copy ("提示 / 确认 / 取消" by default) rather than an empty string.
- The confirm button defaults to the theme
primarycolor and the cancel button tocontentColor; title, content and button styles can be overridden withtitle-style,content-style,confirm-styleandcancel-stylerespectively. clearLoading()is exposed via ref, so the confirm button's loading state can be cleared externally.global/pageare switches reserved for functional invocation (paired withuseModal()); that API is not exported in the current version, so prefer the controlledv-modelapproach for now.