Modal对话框
用于需要用户响应的操作或信息展示
打开方式
支持两种打开方式 使用 trigger插槽 或 ModalRef
使用 trigger插槽 时点击即可自动打开抽屉
使用 ModalRef 时需自行调用
open方法
<template>
<div class="flex flex-col gap-y-4">
<Modal>
<template #trigger>
<div class="btn">点击trigger插槽打开</div>
</template>
<template #body>
<p>这是点击trigger插槽打开的对话框</p>
</template>
</Modal>
<div class="btn" @click="handleOpenModal">使用 open 方法打开</div>
<Modal ref="drawerRef">
<template #body>
<p>这是使用open方法打开的对话框</p>
</template>
</Modal>
</div>
</template>
<script setup lang="ts">
import { Modal } from 'li-daisy'
import type { ModalRef } from 'li-daisy'
import { ref } from 'vue'
const drawerRef = ref<ModalRef>()
const handleOpenModal = () => {
drawerRef.value?.open()
}
</script>打开方向
direction可选值有
ltrrtlmiddlettbbtt,默认值为 无打开方向居中显示
<template>
<div class="grid gap-4 grid-cols-3 min-w-sm">
<div></div>
<Modal direction="ttb">
<template #body>
<h3 class="font-bold text-lg">从上到下 (ttb)</h3>
<p class="py-4">This is the modal content.</p>
</template>
<template #trigger>
<div class="btn">上↓下</div>
</template>
</Modal>
<div></div>
<Modal direction="ltr">
<template #body>
<h3 class="font-bold text-lg">从左到右 (ltr)</h3>
<p class="py-4">This is the modal content.</p>
</template>
<template #trigger>
<div class="btn">左→右</div>
</template>
</Modal>
<Modal direction="middle">
<template #body>
<h3 class="font-bold text-lg">中间 (middle)</h3>
<p class="py-4">This is the modal content.</p>
</template>
<template #trigger>
<div class="btn">中间</div>
</template>
</Modal>
<Modal direction="rtl">
<template #body>
<h3 class="font-bold text-lg">从右到左 (rtl)</h3>
<p class="py-4">This is the modal content.</p>
</template>
<template #trigger>
<div class="btn">左←右</div>
</template>
</Modal>
<div></div>
<Modal direction="btt">
<template #body>
<h3 class="font-bold text-lg">从下到上 (btt)</h3>
<p class="py-4">This is the modal content.</p>
</template>
<template #trigger>
<div class="btn">上↑下</div>
</template>
</Modal>
</div>
</template>
<script setup lang="ts">
import { Modal } from 'li-daisy'
</script>设置大小/支持响应式
注意
该本质是绑定到Modal上的动态css,所有使用的要尤其小心,避免造成副作用
通过size设置宽度大小,支持 Tailwind CSS 的任意宽度值(包括响应式写法)
不设置方向时,即居中显示时:modal默认设置了
max-width为512px当direction为
ttb或btt要设置对应的heightmax-height当direction为
ltr或rtl要设置对应的widthmax-width自行定义的时候要修改
widthmax-width或heigthmax-heigth
<template>
<div>
<Modal
ref="modalRef"
direction="ltr"
size="w-[80vw] min-w-[200px] md:w-[60vw] md:max-w-[400px] lg:w-[50vw] lg:max-w-[600px]"
>
<template #body>
<h3 class="font-bold text-lg">动态大小</h3>
<p class="py-4">调整屏幕大小,观察modal宽度</p>
</template>
</Modal>
<button class="btn" @click="handleOpenModal">打开动态modal</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { Modal, type ModalRef } from 'li-daisy'
const modalRef = ref<ModalRef>()
const handleOpenModal = () => {
modalRef.value?.open()
}
</script>显示关闭图标
通过设置
show-close-icon来控制是否显示图标,默认值为true
<template>
<div class="flex w-full justify-between gap-x-5">
<Modal ref="modalRef1" show-close-icon>
<template #body>
<h3 class="font-bold text-lg">该modal有关闭图标</h3>
<p class="py-4">该modal有关闭图标</p>
</template>
</Modal>
<button class="btn" @click="handleOpenModal1">该modal有关闭图标</button>
<Modal ref="modalRef2" :show-close-icon="false">
<template #body>
<h3 class="font-bold text-lg">该modal无关闭图标</h3>
<p class="py-4">该modal无关闭图标</p>
</template>
</Modal>
<button class="btn" @click="handleOpenModal2">该modal无关闭图标</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { Modal, type ModalRef } from 'li-daisy'
const modalRef1 = ref<ModalRef>()
const handleOpenModal1 = () => {
modalRef1.value?.open()
}
const modalRef2 = ref<ModalRef>()
const handleOpenModal2 = () => {
modalRef2.value?.open()
}
</script>点击蒙层关闭
通过设置
close-on-click-modal来控制点击图层是否关闭,默认值为true
IMPORTANT
当设置了 close-on-click-modal 为true时,关闭图标不再受控制,必然显示
<template>
<div class="flex w-full justify-between gap-x-5">
<Modal ref="modalRef1" :close-on-click-modal="true">
<template #body>
<h3 class="font-bold text-lg">当前点击蒙层可关闭抽屉</h3>
<p class="py-4">当前点击蒙层可关闭modal</p>
</template>
</Modal>
<button class="btn" @click="handleOpenModal1">点击蒙层可关闭</button>
<Modal ref="modalRef2" :close-on-click-modal="false">
<template #body>
<h3 class="font-bold text-lg">当前点击蒙层不可关闭抽屉</h3>
<p class="py-4">当前点击蒙层不可关闭抽屉</p>
</template>
</Modal>
<button class="btn" @click="handleOpenModal2">点击蒙层不可关闭</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { Modal, type ModalRef } from 'li-daisy'
const modalRef1 = ref<ModalRef>()
const handleOpenModal1 = () => {
modalRef1.value?.open()
}
const modalRef2 = ref<ModalRef>()
const handleOpenModal2 = () => {
modalRef2.value?.open()
}
</script>emit
<template>
<div>
<Modal ref="modalRef" @open="handleOpen" @close="handleClose">
<template #body>
<h3 class="font-bold text-lg">emit例子</h3>
<p class="py-4">emit例子</p>
</template>
</Modal>
<button class="btn" @click="handleOpenModal">emit例子</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { Message, Modal, type ModalRef } from 'li-daisy'
const modalRef = ref<ModalRef>()
const handleOpenModal = () => {
modalRef.value?.open()
}
const handleOpen = () => {
Message.success('modal被打开了')
}
const handleClose = () => {
Message.warning('modal被关闭了')
}
</script>关闭时注销组件
destroy-on-close 属性决定关闭 modal 时是否卸载组件,默认为 false
需要每次打开弹窗都初始化内容时,建议设置
destroy-on-close为true需要保留弹窗内表单、计数器等状态时,建议保持默认(
false)效果类似于 keep-alive
<template>
<div class="flex gap-8">
<!-- 会卸载内容的弹窗 -->
<div>
<Modal ref="modalRef1" :destroy-on-close="true">
<template #body>
<h3 class="font-bold text-lg">关闭时卸载组件</h3>
<p class="py-4">弹窗关闭后,内部内容会被卸载,重新打开会重新挂载。</p>
<Count />
</template>
</Modal>
<button class="btn" @click="handleOpenModal1">打开弹窗(卸载内容)</button>
</div>
<!-- 不会卸载内容的弹窗 -->
<div>
<Modal ref="modalRef2">
<template #body>
<h3 class="font-bold text-lg">关闭时不卸载组件</h3>
<p class="py-4">弹窗关闭后,内部内容不会被卸载,重新打开会保留上次状态。</p>
<Count />
</template>
</Modal>
<button class="btn" @click="handleOpenModal2">打开弹窗(保留内容)</button>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { Modal, type ModalRef } from 'li-daisy'
import Count from '../demo/Count.vue'
const modalRef1 = ref<ModalRef>()
const modalRef2 = ref<ModalRef>()
const handleOpenModal1 = () => {
modalRef1.value?.open()
}
const handleOpenModal2 = () => {
modalRef2.value?.open()
}
</script>自定义header
可使用 header 插槽自定义抽屉头部,并且该插槽暴露一个 close 方法用于关闭抽屉
IMPORTANT
由于自定义了header,由此此时 show-close-icon 将不再有实际作用
同理,若将 close-on-click-modal 设置为 false,请务必确保留有关闭的按钮或图标等,以此确保用户体验
<template>
<div>
<Modal ref="modalRef" :close-on-click-modal="false">
<template #header="{ close }">
<div class="flex w-full justify-between border-b border-b-base-300 p-3">
<h2 class="font-bold">自定义header</h2>
<div class="btn btn-circle btn-xs text-lg" @click="close">×</div>
</div>
</template>
<template #body>
<p>这是body</p>
</template>
</Modal>
<button class="btn" @click="handleOpenModal">自定义header</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { Modal, type ModalRef } from 'li-daisy'
const modalRef = ref<ModalRef>()
const handleOpenModal = () => {
modalRef.value?.open()
}
</script>去除body插槽的padding
通过设置
no-body-padding属性,可以去除 Modal 内容区域(body 插槽)的默认内边距,方便你自定义内容样式默认情况下 body 区域会有适当的 padding,设置为
true后将完全移除,内容将紧贴容器边缘
API
Attributes
| 属性值 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| size | 抽屉大小 | string | 'w-11/12 max-w-[512px]' |
| show-close-icon | 是否显示关闭图标 | boolean | true |
| close-on-click-modal | 点击蒙层是否关闭抽屉 | boolean | true |
| destroy-on-close | 关闭组件时是否卸载组件 | boolean | false |
| no-body-padding | 是否去除 body 区域的默认 padding | boolean | false |
Slots
| 插槽名 | 说明 |
|---|---|
| trigger | 打开对话框触发器 |
| header | 对话框头部 |
| body | 对话框内容 |
Event
| 名称 | 说明 | 类型 |
|---|---|---|
| open | 打开modal回调 | () => void |
| close | 关闭modal回调 | () => void |
Expose
| 方法名 | 说明 | 类型 |
|---|---|---|
| open | 控制抽屉打开 | () => void |
| close | 控制抽屉关闭 | () => void |