| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- <template>
- <n-modal
- v-model:show="show"
- class="modal-box"
- :style="{ width: modalOptions.width, ...modalOptions.modalStyle }"
- :preset="undefined"
- size="huge"
- :bordered="false"
- @after-leave="onAfterLeave"
- >
- <n-card :style="modalOptions.contentStyle" :closable="modalOptions.closable" @close="close()">
- <template #header>
- <header class="modal-header">
- {{ modalOptions.title }}
- </header>
- </template>
- <slot />
- <!-- 底部按钮 -->
- <template #footer>
- <slot name="footer">
- <footer v-if="modalOptions.showFooter" class="flex justify-end">
- <n-button v-if="modalOptions.showCancel" @click="handleCancel()">
- {{ modalOptions.cancelText }}
- </n-button>
- <n-button
- v-if="modalOptions.showOk"
- type="primary"
- :loading="modalOptions.okLoading"
- class="ml-20"
- @click="handleOk()"
- >
- {{ modalOptions.okText }}
- </n-button>
- </footer>
- </slot>
- </template>
- </n-card>
- </n-modal>
- </template>
- <script setup>
- import { initDrag } from './utils'
- const props = defineProps({
- width: {
- type: String,
- default: '800px',
- },
- title: {
- type: String,
- default: '',
- },
- closable: {
- type: Boolean,
- default: true,
- },
- cancelText: {
- type: String,
- default: '取消',
- },
- okText: {
- type: String,
- default: '确定',
- },
- showFooter: {
- type: Boolean,
- default: true,
- },
- showCancel: {
- type: Boolean,
- default: true,
- },
- showOk: {
- type: Boolean,
- default: true,
- },
- modalStyle: {
- type: Object,
- default: () => {},
- },
- contentStyle: {
- type: Object,
- default: () => {},
- },
- onOk: {
- type: Function,
- default: () => {},
- },
- onCancel: {
- type: Function,
- default: () => {},
- },
- })
- // 声明一个show变量,用于控制模态框的显示与隐藏
- const show = ref(false)
- // 声明一个modalOptions变量,用于存储模态框的配置信息
- const modalOptions = ref({})
- const okLoading = computed({
- get() {
- return !!modalOptions.value?.okLoading
- },
- set(v) {
- if (modalOptions.value) {
- modalOptions.value.okLoading = v
- }
- },
- })
- // 打开模态框
- async function open(options = {}) {
- // 将props和options合并赋值给modalOptions
- modalOptions.value = { ...props, ...options }
- // 将show的值设置为true
- show.value = true
- await nextTick()
- initDrag(
- Array.prototype.at.call(document.querySelectorAll('.modal-header'), -1),
- Array.prototype.at.call(document.querySelectorAll('.modal-box'), -1),
- )
- }
- // 定义一个close函数,用于关闭模态框
- function close() {
- show.value = false
- }
- // 定义一个handleOk函数,用于处理模态框确定操作
- async function handleOk(data) {
- // 如果modalOptions中没有onOk函数,则直接关闭模态框
- if (typeof modalOptions.value.onOk !== 'function') {
- return close()
- }
- try {
- // 调用onOk函数,传入data参数
- const res = await modalOptions.value.onOk(data)
- // 如果onOk函数的返回值不为false,则关闭模态框
- if (res !== false)
- close()
- }
- catch (error) {
- console.error(error)
- okLoading.value = false
- }
- }
- // 定义一个handleCancel函数,用于处理模态框取消操作
- async function handleCancel(data) {
- // 如果modalOptions中没有onCancel函数,则直接关闭模态框
- if (typeof modalOptions.value.onCancel !== 'function') {
- return close()
- }
- try {
- // 调用onCancel函数,传入data参数
- const res = await modalOptions.value.onCancel(data)
- // 如果onCancel函数的返回值不为false,则关闭模态框
- if (res !== false)
- close()
- }
- catch (error) {
- console.error(error)
- okLoading.value = false
- }
- }
- async function onAfterLeave() {
- await nextTick()
- initDrag(
- Array.prototype.at.call(document.querySelectorAll('.modal-header'), -1),
- Array.prototype.at.call(document.querySelectorAll('.modal-box'), -1),
- )
- }
- // 定义一个defineExpose函数,用于暴露open、close、handleOk、handleCancel函数
- defineExpose({
- open,
- close,
- handleOk,
- handleCancel,
- okLoading,
- options: modalOptions,
- })
- </script>
|