Dialog
Examples
Sizes and fullscreen
Available size/dimensional variants for the ui
prop: s
/ m
/ narrow
/ medium
/ wide
/ auto
.
s
/ m
are used to specify size for internal content and will be inherited by components inside the dialog. While narrow
/ medium
/ wide
/ fullscreen
/ auto
are used to specify the dimension of the dialog itself, thus can be used together with s
/ m
.
<template>
<article>
<veui-button
class="button"
@click="openDialog('s')"
>
s
</veui-button>
<veui-button
class="button"
@click="openDialog('m')"
>
m
</veui-button>
<veui-button
class="button"
@click="openDialog('narrow')"
>
narrow
</veui-button>
<veui-button
class="button"
@click="openDialog('medium')"
>
medium
</veui-button>
<veui-button
class="button"
@click="openDialog('wide')"
>
wide
</veui-button>
<veui-button
class="button"
@click="openDialog('fullscreen')"
>
fullscreen
</veui-button>
<veui-button
class="button"
@click="openDialog('auto')"
>
auto
</veui-button>
<veui-dialog
title="System"
:ui="ui"
:open.sync="open"
>
<section>Current UI: "{{ ui }}"</section>
<section v-if="ui === 's' || ui === 'm'">
<veui-button class="button">
Button size: {{ ui }}
</veui-button>
<veui-switch>{{ ui }}</veui-switch>
</section>
</veui-dialog>
</article>
</template>
<script>
import { Dialog, Button, Switch } from 'veui'
export default {
components: {
'veui-dialog': Dialog,
'veui-button': Button,
'veui-switch': Switch
},
data () {
return {
open: false,
ui: null
}
},
methods: {
openDialog (size) {
this.ui = size
this.open = true
}
}
}
</script>
<style lang="less" scoped>
.button {
margin-right: 20px;
}
</style>
Modal and non-modal
<template>
<article>
<veui-button
class="button"
@click="modalOpen = true"
>
Modal
</veui-button>
<veui-button
class="button"
@click="nonModalOpen = true"
>
Non-modal
</veui-button>
<veui-dialog
title="System"
:open.sync="modalOpen"
@ok="handleModalClose(true)"
@cancel="handleModalClose"
>
Do you want to refresh the page?
</veui-dialog>
<veui-dialog
title="System"
:open.sync="nonModalOpen"
:modal="false"
@ok="handleModalClose(true)"
@cancel="handleModalClose"
>
Do you want to refresh the page?
</veui-dialog>
</article>
</template>
<script>
import { Dialog, Button } from 'veui'
export default {
components: {
'veui-dialog': Dialog,
'veui-button': Button
},
data () {
return {
modalOpen: false,
nonModalOpen: false
}
},
methods: {
handleModalClose (ok) {
this.modalOpen = false
if (ok) {
location.reload()
}
},
handleNonModalClose (ok) {
this.nonModalOpen = false
if (ok) {
location.reload()
}
}
}
}
</script>
<style lang="less" scoped>
.button {
margin-right: 20px;
}
</style>
Custom content
<template>
<article>
<veui-button
class="button"
@click="simpleOpen = true"
>
Title & content
</veui-button>
<veui-dialog
:open.sync="simpleOpen"
title="Customized Title & Content"
@ok="simpleOpen = false"
@cancel="simpleOpen = false"
>
Customized content via <code>&lt;slot&gt;</code>.
</veui-dialog>
<veui-button
class="button"
@click="titleIconOpen = true"
>
Icon in Title
</veui-button>
<veui-dialog
:open.sync="titleIconOpen"
@ok="titleIconOpen = false"
@cancel="titleIconOpen = false"
>
<template #title>
Title with Icon <veui-icon name="flag"/>
</template>
Customized content via <code>&lt;slot&gt;</code>.
</veui-dialog>
<veui-button
class="button"
@click="footOpen = true"
>
Foot
</veui-button>
<veui-dialog
:open.sync="footOpen"
title="Customized Foot"
>
Customized content via <code>&lt;slot&gt;</code>.
<template #foot="{ close }">
<veui-button
ui="s primary"
@click="close('ok')"
>
Close
</veui-button>
</template>
</veui-dialog>
</article>
</template>
<script>
import { Dialog, Button, Icon } from 'veui'
import 'veui-theme-dls-icons/flag'
export default {
components: {
'veui-dialog': Dialog,
'veui-button': Button,
'veui-icon': Icon
},
data () {
return {
simpleOpen: false,
titleIconOpen: false,
footOpen: false
}
}
}
</script>
<style lang="less" scoped>
.button {
margin-right: 20px;
}
</style>
Async support
When you want a unified process to handle all user interactions that might trigger the dialog to be closed, you can leverage the before-close
function prop. No matter the close behavior is about to be triggered by clicking “OK”/“Cancel” buttons, the close button or pressing esc, before-close
will always take over the following process. If the logic is relatively simple, you can manipulate open
prop directly to close the dialog.
<template>
<article>
<veui-button
class="button"
:disabled="submitting"
@click="submitOpen = true"
>
Submit
</veui-button>
<veui-button
class="button"
:disabled="saving"
@click="saveOpen = true"
>
Save
</veui-button>
<veui-dialog
title="System"
:open.sync="submitOpen"
:before-close="submit"
:closable="false"
:escapable="!submitting"
:loading="submitting"
>
Confirm to create the issue?
</veui-dialog>
<veui-dialog
title="System"
:open.sync="saveOpen"
:closable="false"
:escapable="!submitting"
>
Confirm to save the post?
<template #foot>
<veui-button
ui="primary"
:loading="saving"
@click="save('ok')"
>
OK
</veui-button>
<veui-button
:disabled="saving"
@click="save"
>
Cancel
</veui-button>
</template>
</veui-dialog>
</article>
</template>
<script>
import { Dialog, Button, toast } from 'veui'
function fakeRequest () {
return new Promise(resolve =>
setTimeout(() => {
resolve(Math.random() < 0.5)
}, 2000)
)
}
export default {
components: {
'veui-dialog': Dialog,
'veui-button': Button
},
data () {
return {
submitOpen: false,
saveOpen: false,
submitting: false,
saving: false
}
},
methods: {
submit (type) {
if (type === 'ok') {
this.submitting = true
return fakeRequest().then(success => {
this.submitting = false
if (!success) {
toast.error('Failed to create the issue. Please retry.')
return false
}
toast.success('Issue created successfully!')
})
}
},
save (type) {
if (type === 'ok') {
this.saving = true
return fakeRequest().then(success => {
this.saving = false
if (!success) {
toast.error('Failed to save the post. Please retry.')
} else {
toast.success('Post saved successfully!')
this.saveOpen = false
}
})
}
this.saveOpen = false
}
}
}
</script>
<style lang="less" scoped>
.button {
margin-right: 20px;
}
</style>
Draggable
<template>
<article>
<veui-button @click="draggableOpen = true">
Draggable
</veui-button>
<veui-dialog
:open.sync="draggableOpen"
title="Draggable Dialog"
draggable
@ok="draggableOpen = false"
@cancel="draggableOpen = false"
>
This dialog is draggable.
</veui-dialog>
</article>
</template>
<script>
import { Dialog, Button } from 'veui'
export default {
components: {
'veui-dialog': Dialog,
'veui-button': Button
},
data () {
return {
draggableOpen: false
}
}
}
</script>
Stacking order
Open both dialogs and drag one of them to make them overlap a little bit. Then when you activate one dialog, it will be displayed on top of the other one.
<template>
<article>
<veui-button
class="button"
@click="aOpen = true"
>
Dialog A
</veui-button>
<veui-dialog
:open.sync="aOpen"
title="Dialog A"
draggable
:modal="false"
@ok="aOpen = false"
@cancel="aOpen = false"
>
The content of Dialog A.
</veui-dialog>
<veui-button
class="button"
@click="bOpen = true"
>
Dialog B
</veui-button>
<veui-dialog
:open.sync="bOpen"
title="Dialog B"
draggable
:modal="false"
@ok="bOpen = false"
@cancel="bOpen = false"
>
The content of Dialog B.
</veui-dialog>
</article>
</template>
<script>
import { Dialog, Button } from 'veui'
export default {
components: {
'veui-dialog': Dialog,
'veui-button': Button
},
data () {
return {
aOpen: false,
bOpen: false
}
}
}
</script>
<style lang="less" scoped>
.button {
margin-right: 20px;
}
</style>
Loading and disabled states
<template>
<article>
<veui-button @click="open = true">
Open Dialog
</veui-button>
<veui-dialog
:open.sync="open"
title="Dialog State"
:loading="loading"
:disabled="disabled"
>
<veui-stack gap="m">
<veui-checkbox v-model="loading">
Loading
</veui-checkbox>
<veui-checkbox
v-model="disabled"
class="ml-3p"
>
Disabled
</veui-checkbox>
</veui-stack>
</veui-dialog>
</article>
</template>
<script>
import { Dialog, Button, Stack, Checkbox } from 'veui'
export default {
components: {
'veui-dialog': Dialog,
'veui-button': Button,
'veui-stack': Stack,
'veui-checkbox': Checkbox
},
data () {
return {
open: false,
disabled: false,
loading: false
}
}
}
</script>
API
Props
Name | Type | Default | Description | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ui | string | - | The preset style.
| ||||||||||||||||
modal | boolean | true | Whether the dialog is modal. A modal dialog blocks the underlying content (cannot be clicked) and takes focus away (focus returns after the dialog is closed). | ||||||||||||||||
title | string | - | The text for the dialog title. If the title slot is specified, it takes precedence over this prop. | ||||||||||||||||
open | boolean | false |
Whether the dialog box is displayed. | ||||||||||||||||
closable | boolean | true | Whether to show the close button. | ||||||||||||||||
outside-closable | boolean | false | Whether to close the dialog when clicked outside. | ||||||||||||||||
draggable | boolean | false | Whether the dialog is draggable. | ||||||||||||||||
escapable | boolean | false | Whether pressing esc can close the dialog. This only takes effect when closable is true . | ||||||||||||||||
inline | boolean | false | Whether to inline the dialog and occupy content space. | ||||||||||||||||
footless | boolean | false | Whether to hide the default bottom bar. | ||||||||||||||||
loading | boolean | false | Whether the dialog is in a loading state. When in a loading state, the OK button also enters a loading state and cannot be clicked. | ||||||||||||||||
disabled | boolean | false | Whether the dialog is in a disabled state. When in a disabled state, the OK button also enters a disabled state and cannot be clicked. | ||||||||||||||||
ok-label | string | - | The text for the "OK" button. | ||||||||||||||||
cancel-label | string | - | The text for the "Cancel" button. | ||||||||||||||||
priority | number | - | The stacking order of the dialog layer, refer to the Overlay component's priority prop. | ||||||||||||||||
before-close | function(string): boolean=|Promise<boolean> | - | Executed after the action that triggers the closing of the dialog box occurs, with a type of
| ||||||||||||||||
overlay-class | string | Object | - | The class name of the dialog layer root element, refer to the Overlay component's overlay-class prop. | ||||||||||||||||
overlay-style | string | Array | Object | - | Refer to the Overlay component's overlay-style prop. |
Slots
Name | Description | ||||||
---|---|---|---|---|---|---|---|
default | Content area. | ||||||
title | Title area. If both the title prop and the title slot are specified, the latter takes precedence. | ||||||
foot | Footer area. By default, the "OK" and "Cancel" buttons are displayed.
|
Events
Name | Description |
---|---|
ok | Triggered when the "OK" button is clicked or when the scope function close('ok') is called. |
cancel | Triggered when the "Cancel" button is clicked, when the close button is clicked, when the dialog box is closed by pressing esc, or when the scope function close('cancel') is called. |
<value> | Triggered when the scope function close(value) is called. |
afteropen | Triggered after the dialog box is opened. The content of the dialog box is rendered only after it is opened, so if there is logic that depends on the content being rendered, it should be executed after this event is triggered. |
afterclose | Triggered after the dialog box is closed. If the style theme provides an exit animation, it will be triggered after the exit animation is complete. |
Icons
Name | Description |
---|---|
close | Close. |
CSS
Name | Type | Default | Description |
---|---|---|---|
--dls-dialog-width | <length> | - | The width of the entire dialog box. Cannot be set at the same time as |
--dls-dialog-content-width | <length> | - | The width of the content area of the dialog box. Cannot be set at the same time as |