用法
使用 v-model
来控制模态框的状态。
<script setup lang="ts">
const isOpen = ref(false)
</script>
<template>
<div>
<UButton label="Open" @click="isOpen = true" />
<UModal v-model="isOpen">
<div class="p-4">
<Placeholder class="h-48" />
</div>
</UModal>
</div>
</template>
您可以在模态框中放入 卡片 组件来处理表单并利用 header
和 footer
插槽。
<script setup lang="ts">
const isOpen = ref(false)
</script>
<template>
<div>
<UButton label="Open" @click="isOpen = true" />
<UModal v-model="isOpen">
<UCard :ui="{ ring: '', divide: 'divide-y divide-gray-100 dark:divide-gray-800' }">
<template #header>
<Placeholder class="h-8" />
</template>
<Placeholder class="h-32" />
<template #footer>
<Placeholder class="h-8" />
</template>
</UCard>
</UModal>
</div>
</template>
禁用覆盖层
将 overlay
属性设置为 false
以禁用它。
<script setup lang="ts">
const isOpen = ref(false)
</script>
<template>
<div>
<UButton label="Open" @click="isOpen = true" />
<UModal v-model="isOpen" :overlay="false">
<div class="p-4">
<Placeholder class="h-48" />
</div>
</UModal>
</div>
</template>
禁用过渡动画
将 transition
属性设置为 false
以禁用它。
<script setup lang="ts">
const isOpen = ref(false)
</script>
<template>
<div>
<UButton label="Open" @click="isOpen = true" />
<UModal v-model="isOpen" :transition="false">
<div class="p-4">
<Placeholder class="h-48" />
</div>
</UModal>
</div>
</template>
阻止关闭
使用 prevent-close
属性来禁用外部点击以及 esc
键盘快捷键。当用户尝试关闭模态框时,将发出 close-prevented
事件。
<script setup lang="ts">
const isOpen = ref(false)
</script>
<template>
<div>
<UButton label="Open" @click="isOpen = true" />
<UModal v-model="isOpen" prevent-close>
<UCard :ui="{ ring: '', divide: 'divide-y divide-gray-100 dark:divide-gray-800' }">
<template #header>
<div class="flex items-center justify-between">
<h3 class="text-base font-semibold leading-6 text-gray-900 dark:text-white">
Modal
</h3>
<UButton color="gray" variant="ghost" icon="i-heroicons-x-mark-20-solid" class="-my-1" @click="isOpen = false" />
</div>
</template>
<Placeholder class="h-32" />
</UCard>
</UModal>
</div>
</template>
您仍然可以使用我们的 defineShortcuts 可组合函数来自行处理 esc
快捷键。
<script setup lang="ts">
const isOpen = ref(false)
defineShortcuts({
escape: {
usingInput: true,
whenever: [isOpen],
handler: () => { isOpen.value = false }
}
})
</script>
全屏
将 fullscreen
属性设置为 true
以启用它。
<script setup lang="ts">
const isOpen = ref(false)
</script>
<template>
<div>
<UButton label="Open" @click="isOpen = true" />
<UModal v-model="isOpen" fullscreen>
<UCard
:ui="{
base: 'h-full flex flex-col',
rounded: '',
divide: 'divide-y divide-gray-100 dark:divide-gray-800',
body: {
base: 'grow'
}
}"
>
<template #header>
<div class="flex items-center justify-between">
<h3 class="text-base font-semibold leading-6 text-gray-900 dark:text-white">
Modal
</h3>
<UButton color="gray" variant="ghost" icon="i-heroicons-x-mark-20-solid" class="-my-1" @click="isOpen = false" />
</div>
</template>
<Placeholder class="h-full" />
</UCard>
</UModal>
</div>
</template>
以编程方式控制
首先,将 Modals
组件添加到您的应用程序中,最好是在 app.vue
中。此组件为您的应用程序提供了一个位置来渲染以编程方式创建的模态框。
app.vue
<template>
<div>
<UContainer>
<NuxtPage />
</UContainer>
<UModals />
</div>
</template>
然后,您可以使用 useModal
可组合函数来控制应用程序中的模态框。
<script setup lang="ts">
import { ModalExampleComponent } from '#components'
const toast = useToast()
const modal = useModal()
const count = ref(0)
function openModal() {
count.value += 1
modal.open(ModalExampleComponent, {
count: count.value,
onSuccess() {
toast.add({
title: 'Success !',
id: 'modal-success'
})
}
})
}
</script>
<template>
<UButton label="Reveal modal" @click="openModal" />
</template>
此外,您可以在模态框组件中通过调用 modal.close()
来关闭模态框。
属性
ui
{ wrapper?: string; inner?: string; container?: string; padding?: string; margin?: string; base?: string; overlay?: DeepPartial<{ base: string; background: string; transition: { enter: string; enterFrom: string; enterTo: string; leave: string; leaveFrom: string; leaveTo: string; }; }, any>; ... 7 more ...; transitio...
{}
transition
布尔值
true
modelValue
布尔值
false
appear
布尔值
false
overlay
布尔值
true
fullscreen
布尔值
false
preventClose
布尔值
false
配置
{
wrapper: 'relative z-50',
inner: 'fixed inset-0 overflow-y-auto',
container: 'flex min-h-full items-end sm:items-center justify-center text-center',
padding: 'p-4 sm:p-0',
margin: 'sm:my-8',
base: 'relative text-left rtl:text-right flex flex-col',
overlay: {
base: 'fixed inset-0 transition-opacity',
background: 'bg-gray-200/75 dark:bg-gray-800/75',
transition: {
enter: 'ease-out duration-300',
enterFrom: 'opacity-0',
enterTo: 'opacity-100',
leave: 'ease-in duration-200',
leaveFrom: 'opacity-100',
leaveTo: 'opacity-0'
}
},
background: 'bg-white dark:bg-gray-900',
ring: '',
rounded: 'rounded-lg',
shadow: 'shadow-xl',
width: 'w-full sm:max-w-lg',
height: '',
fullscreen: 'w-screen h-screen',
transition: {
enter: 'ease-out duration-300',
enterFrom: 'opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95',
enterTo: 'opacity-100 translate-y-0 sm:scale-100',
leave: 'ease-in duration-200',
leaveFrom: 'opacity-100 translate-y-0 sm:scale-100',
leaveTo: 'opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95'
}
}