Skip to content

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

ParameterDescriptionTypeOptionsDefault
v-modelWhether to showBooleanfalse
titleTitle. If a custom header slot is used, the title prop is ignored.String
widthDialog widthString520px
topDistance from the top of the viewportString100px
show-closeShow close button in the top-right cornerBooleantrue
mask-closableAllow clicking the mask to closeBooleantrue
esc-closableWhether to allow closing via ESC keyBooleantrue
fullscreenWhether to show in fullscreenBooleanfalse
draggableWhether the dialog can be draggedBooleanfalse
maskWhether to show maskBooleantrue
mask-classCustom mask class nameString
custom-classCustom class nameString
body-stylesCustom body stylesObject
z-indexZ-index levelNumber, default is 2000, the dialog auto-increments; if this value is set, it starts auto-incrementing from the set value0
append-to-bodyWhether to append the dialog to the bodyBooleanfalse
lock-scrollLock scrolling when the modal appearsBooleantrue
transition-nameDialog animationString'dialog-fade'
open-delayOpen delay (milliseconds)Number0
close-delayClose delay (milliseconds)Number0
before-closeCallback before closing, can pause closingFunction(done) done is used for closing
destroy-on-closeDestroy inner elements on close, mainly used for elements that need re-initializationBooleanfalse
screen-centerCenter dialog on screen (centered horizontally and vertically)Booleanfalse
max-heightMaximum dialog height (effective when screen-center is enabled)String'calc(100vh - 80px)'

Events

Event NameDescriptionReturn Value
openmodalopenCallback
openedCallback when open animation completes
closeModal close callback
closedCallback when close animation ends

Slot

NameDescription
titleCustom title
ctrlLeft side of close button control slot
footerCustom table footer content