Dialog 对话框
示例
尺寸与全屏
可供选用的 ui
属性值:s
/ m
/ narrow
/ medium
/ wide
/ auto
。
s
/ m
用于指定内容的尺寸,会被继承到内部的组件上。而 narrow
/ medium
/ wide
/ fullscreen
/ auto
是对话框本身所占区域的大小,可以与 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>
模态与非模态
<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>
自定义内容
<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>
异步支持
当你希望统一处理用户可能触发对话框关闭的操作,请使用 before-close
属性传入统一的处理函数,此时无论是点击“确定”/“取消”按钮、关闭按钮还是按下 esc 触发的关闭操作,都会统一进入 before-close
的处理流程。如果逻辑相对简单,比如取消时没有额外逻辑,可以直接操作 open
属性来关闭对话框。
<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>
可拖拽
<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>
层叠顺序
同时打开上面两个对话框,将一个拖动到使两个对话框稍稍重叠的位置。然后当你点击激活一个对话框,它就将显示于另一个之上了。
<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>
加载与禁用态
<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
属性
名称 | 类型 | 默认值 | 描述 | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ui | string | - | 预设样式。
| ||||||||||||||||
modal | boolean | true | 是否是模态对话框。模态对话框默认遮挡底层(无法点击)且抢占焦点(关闭后焦点会回归)。 | ||||||||||||||||
title | string | - | 对话框标题文本。如果指定了 title 插槽,则优先使用 title 插槽。 | ||||||||||||||||
open | boolean | false |
是否显示对话框。 | ||||||||||||||||
closable | boolean | true | 是否显示关闭按钮。 | ||||||||||||||||
outside-closable | boolean | false | 点击对话框外部时是否关闭对话框。 | ||||||||||||||||
draggable | boolean | false | 是否可拖拽。 | ||||||||||||||||
escapable | boolean | false | 按下 esc 键是否可以关闭对话框。仅在 closable 为 true 时生效。 | ||||||||||||||||
inline | boolean | false | 是否内联在内容中显示并占用内容空间。 | ||||||||||||||||
footless | boolean | false | 是否不显示默认的底部操作栏。 | ||||||||||||||||
loading | boolean | false | 是否处于加载状态。处于加载状态时确定按钮也将进入加载状态,无法点击。 | ||||||||||||||||
disabled | boolean | false | 是否处于禁用状态。处于禁用状态时确定按钮也将进入禁用状态,无法点击。 | ||||||||||||||||
ok-label | string | - | “确定”按钮的文字内容。 | ||||||||||||||||
cancel-label | string | - | “取消”按钮的文字内容。 | ||||||||||||||||
priority | number | - | 对话框浮层层叠权重,参考 Overlay 组件的 priority 属性。 | ||||||||||||||||
before-close | function(string): boolean=|Promise<boolean=> | - | 在将触发对话框关闭的操作发生后执行,类型为
| ||||||||||||||||
overlay-class | string | Object | - | 对话框浮层根元素类名,参考 Overlay 组件的 overlay-class 属性。 | ||||||||||||||||
overlay-style | string | Array | Object | - | 参考 Overlay 组件的 overlay-style 属性。 |
插槽
名称 | 描述 | ||||||
---|---|---|---|---|---|---|---|
default | 内容区。 | ||||||
title | 标题区。若同时指定了 title 属性和 title 插槽,以后者为准。 | ||||||
foot | 底部区域,默认会展示“确定”、“取消”按钮。
|
事件
名称 | 描述 |
---|---|
ok | 点击“确定”按钮时或通过调用作用域函数 close('ok') 时触发。 |
cancel | 点击“取消”按钮、关闭按钮、通过 esc 关闭对话框时,或者通过调用作用域函数 close('cancel') 时触发。 |
<value> | 通过调用作用域函数 close(value) 时触发。 |
afteropen | 对话框打开后触发。对话框内容在打开后才会进行渲染,所以如果有依赖内容渲染的逻辑,请在此事件触发后再执行。 |
afterclose | 对话框关闭后触发。如果样式主题提供了退出动画,将在退出动画完毕后触发。 |
图标
名称 | 描述 |
---|---|
close | 关闭。 |
自定义样式
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
--dls-dialog-width | <length> | - | 整个对话框的宽度。不能与 |
--dls-dialog-content-width | <length> | - | 对话框内容区域的宽度。不能与 |