Modal
A dialog/modal displayed as a floating layer to guide user interactions.
Basic Usage
<template>
<div>
<b-button type="primary" @click="visible = true">Open</b-button>
<b-button type="primary" @click="confirm = true">Confirm</b-button>
<b-modal v-model="visible" title="Basic Modal Title" :z-index="1000">
<p>This is the dialog content....</p>
<p>This is the dialog content....</p>
<p>This is the dialog content....</p>
<template #footer>
<span>
<b-button @click="onClose">Cancel</b-button>
<b-button type="primary" @click="onOk">Confirm</b-button>
</span>
</template>
</b-modal>
<b-modal v-model="confirm" width="420px" :show-close="false">
<div class="p8">
<div class="f-s-18" flex="cross:center">
<b-icon name="info-circle" size="24" color="#fa8c16"></b-icon>
<span class="ml-8">Warning</span>
</div>
<div style="padding: 8px 0 8px 32px">Confirm注销Login吗?</div>
<div class="t-right">
<b-button @click="confirm = false">Cancel</b-button>
<b-button type="primary" @click="confirm = false">Confirm</b-button>
</div>
</div>
</b-modal>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { Message } from 'bin-ui-design'
const visible = ref(false)
const confirm = ref(false)
function onOk() {
visible.value = false
Message('clickConfirm')
}
function onClose() {
visible.value = false
Message('clickCancel')
}
</script>Custom Styles
The Modal component provides flexible custom styling APIs and slots, allowing full control over each part of the modal, such as header, footer, and close button.
<template>
<div>
<b-button @click="modal1 = true">Custompage头page脚</b-button>
<b-button @click="modal2 = true">is not title bar or footer</b-button>
<b-button @click="modal3 = true">Set width</b-button>
<b-button @click="modal4 = true">from top200px</b-button>
<b-button @click="modal5 = true">body-style</b-button>
<b-modal v-model="modal1">
<template #title>
<p style="color: #f60; text-align: center">
<span>Custompage头</span>
</p>
</template>
<p>This is the dialog content....</p>
<p>This is the dialog content....</p>
<p>This is the dialog content....</p>
<template #footer>
<b-button type="danger">Delete</b-button>
</template>
</b-modal>
<b-modal v-model="modal2">
<p>This is the dialog content....</p>
<p>This is the dialog content....</p>
<p>This is the dialog content....</p>
</b-modal>
<b-modal v-model="modal3" title="Customwidth" width="300px">
<p>
Customwidth,单位 px,Default 520px。 dialog的width是响应式的,当屏幕size小于 768px
时,width会变为自动auto。
</p>
</b-modal>
<b-modal v-model="modal4" title="from top" top="200px">
<p>from top200px</p>
</b-modal>
<b-modal v-model="modal5" title="body-style" :body-styles="{ padding: '20px' }">
<p>This is the dialog content....</p>
<p>This is the dialog content....</p>
<p>This is the dialog content....</p>
</b-modal>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const modal1 = ref(false)
const modal2 = ref(false)
const modal3 = ref(false)
const modal4 = ref(false)
const modal5 = ref(false)
</script>Center Alignment
Set screen-center to center the dialog on screen, and a default max-height can be configured.
<template>
<div>
<b-button @click="open1">Auto-height centered modal</b-button>
<b-button @click="open2">Centered Modal</b-button>
<b-modal v-model="visible" title="Basic Modal Title" screen-center>
<p v-for="i in rows" :key="i">This is the dialog content....</p>
<template #footer>
<span>
<b-button @click="onClose">Cancel</b-button>
<b-button type="primary" @click="onClose">Confirm</b-button>
</span>
</template>
</b-modal>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const visible = ref(false)
const rows = ref(5)
function open1() {
visible.value = true
rows.value = 30
}
function open2() {
visible.value = true
rows.value = 3
}
function onClose() {
visible.value = false
}
</script>Open Animation
The modal animation can be customized via transition-name. By default, it animates from the click position.
<template>
<div>
<b-space>
<b-radio-group v-model="transitionName" type="capsule">
<b-radio label="dialog-fade"></b-radio>
<b-radio label="fade-in"></b-radio>
<b-radio label="move-right"></b-radio>
<b-radio label="zoom-in-top"></b-radio>
<b-radio label="zoom-in"></b-radio>
<b-radio label="fade-scale-move"></b-radio>
<b-radio label="fade-down"></b-radio>
</b-radio-group>
<b-button @click="modal1 = true">Open</b-button>
</b-space>
<b-modal
v-model="modal1"
:title="`Customanimation${transitionName}`"
:transition-name="transitionName"
>
<p>This is the dialog content....</p>
<p>This is the dialog content....</p>
<p>This is the dialog content....</p>
<template #footer>
<span>
<b-button @click="modal1 = false">Close</b-button>
</span>
</template>
</b-modal>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const modal1 = ref(false)
const transitionName = ref('dialog-fade')
</script>Disable Close
Both the close button and mask close can be disabled.
<template>
<div>
<b-button @click="modal1 = true">DisabledRight Top角Close</b-button>
<b-button @click="modal2 = true">DisabledmaskClose</b-button>
<b-modal v-model="modal1" title="Basic Modal Title" :show-close="false">
<p>DisabledRight Top角Close</p>
</b-modal>
<b-modal v-model="modal2" title="Basic Modal Title" :mask-closable="false">
<p>DisabledmaskClose</p>
</b-modal>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const modal1 = ref(false)
const modal2 = ref(false)
</script>Nesting
Nested modals are generally not recommended, but they can be used.
<template>
<div>
<b-button @click="modal1 = true">showModal 1</b-button>
<b-modal v-model="modal1" title="Modal 1" width="600px">
<p>This is the dialog content....</p>
<p>This is the dialog content....</p>
<p>This is the dialog content....</p>
<b-button type="primary" @click="modal2 = true">OpenNested Modal</b-button>
<b-modal v-model="modal2" title="Nested Modal">
<p>This is the dialog content....</p>
<p>This is the dialog content....</p>
<p>This is the dialog content....</p>
</b-modal>
</b-modal>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const modal1 = ref(false)
const modal2 = ref(false)
</script>Fullscreen
Set fullscreen for fullscreen display. Various controls can be customized.
<template>
<div>
<b-button @click="modal = true">Show fullscreen dialog</b-button>
<b-modal v-model="modal" title="Fullscreen Title" :fullscreen="fullscreen">
<template #ctrl>
<i
:class="`b-iconfont b-icon-fullscreen${fullscreen ? '-exit' : ''}`"
@click="fullscreen = !fullscreen"
></i>
</template>
<div :style="fullscreen ? {} : 'height: 300px; overflow-y: auto'">
<p v-for="i in 50" :key="i">This is the fullscreen content.{{ i }}...</p>
</div>
<template #footer>
<span>
<b-button @click="modal = false">Cancel</b-button>
<b-button type="primary" @click="modal = false">Confirm</b-button>
</span>
</template>
</b-modal>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const modal = ref(false)
const fullscreen = ref(false)
</script>Draggable
Set draggable to make the dialog draggable.
<template>
<div>
<b-button @click="modal1 = true">Opendialog1</b-button>
<b-button @click="modal2 = true">Opendialog2</b-button>
<b-modal v-model="modal1" title="dialog1" draggable>
<p>dialog1Content</p>
</b-modal>
<b-modal v-model="modal2" title="dialog2" draggable :mask="false">
<p>dialog2Content</p>
</b-modal>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const modal1 = ref(false)
const modal2 = ref(false)
</script>Props
| Parameter | Description | Type | Options | Default |
|---|---|---|---|---|
| v-model | Whether to show | Boolean | — | false |
| title | Title. If a custom header slot is used, the title prop is ignored. | String | — | — |
| width | Dialog width | String | — | 520px |
| top | Distance from the top of the viewport | String | — | 100px |
| show-close | Show close button in the top-right corner | Boolean | — | true |
| mask-closable | Allow clicking the mask to close | Boolean | — | true |
| esc-closable | Whether to allow closing via ESC key | Boolean | — | true |
| fullscreen | Whether to show in fullscreen | Boolean | — | false |
| draggable | Whether the dialog can be dragged | Boolean | — | false |
| mask | Whether to show mask | Boolean | — | true |
| mask-class | Custom mask class name | String | — | — |
| custom-class | Custom class name | String | — | — |
| body-styles | Custom body styles | Object | — | — |
| z-index | Z-index level | Number, default is 2000, the dialog auto-increments; if this value is set, it starts auto-incrementing from the set value | — | 0 |
| append-to-body | Whether to append the dialog to the body | Boolean | — | false |
| lock-scroll | Lock scrolling when the modal appears | Boolean | — | true |
| transition-name | Dialog animation | String | — | 'dialog-fade' |
| open-delay | Open delay (milliseconds) | Number | — | 0 |
| close-delay | Close delay (milliseconds) | Number | — | 0 |
| before-close | Callback before closing, can pause closing | Function(done) done is used for closing | — | — |
| destroy-on-close | Destroy inner elements on close, mainly used for elements that need re-initialization | Boolean | — | false |
| screen-center | Center dialog on screen (centered horizontally and vertically) | Boolean | — | false |
| max-height | Maximum dialog height (effective when screen-center is enabled) | String | — | 'calc(100vh - 80px)' |
Events
| Event Name | Description | Return Value |
|---|---|---|
| open | modalopenCallback | — |
| opened | Callback when open animation completes | — |
| close | Modal close callback | — |
| closed | Callback when close animation ends | — |
Slot
| Name | Description |
|---|---|
| title | Custom title |
| ctrl | Left side of close button control slot |
| footer | Custom table footer content |