165 lines
4.4 KiB
Plaintext
165 lines
4.4 KiB
Plaintext
<template>
|
|
<Modal v-bind="getBindValue" @cancel="handleCancel">
|
|
<!--自定义关闭-->
|
|
<template #closeIcon v-if="!$slots.closeIcon">
|
|
<template v-if="canFullscreen">
|
|
<a-tooltip title="还原" placement="bottom" v-if="fullScreenRef" class="mr-1">
|
|
<FullscreenExitOutlined role="full" @click="handleFullScreen" />
|
|
</a-tooltip>
|
|
<a-tooltip v-else title="最大化" placement="bottom" class="mr-1">
|
|
<FullscreenOutlined role="close" @click="handleFullScreen" />
|
|
</a-tooltip>
|
|
</template>
|
|
<a-tooltip title="关闭" placement="bottom">
|
|
<CloseOutlined @click="handleCancel" class="ml-4" />
|
|
</a-tooltip>
|
|
</template>
|
|
|
|
<!--内容区域-->
|
|
<slot name="default"></slot>
|
|
|
|
<!--底部插槽-->
|
|
<template v-if="!$slots.footer" #footer>
|
|
<a-space>
|
|
<slot name="prefixFooter"></slot>
|
|
<a-button v-bind="cancelButtonProps" @click="handleCancel" v-if="getProps.showCancelBtn">{{
|
|
getProps.cancelText
|
|
}}</a-button>
|
|
<slot name="centerFooter"></slot>
|
|
<a-button
|
|
:type="getProps.okType"
|
|
v-bind="okButtonProps"
|
|
:loading="subLoading"
|
|
@click="handleSubmit"
|
|
v-if="getProps.showOkBtn"
|
|
>{{ getProps.okText }}
|
|
</a-button>
|
|
<slot name="suffixFooter"></slot>
|
|
</a-space>
|
|
</template>
|
|
|
|
<template v-else #footer>
|
|
<slot name="action"></slot>
|
|
</template>
|
|
|
|
<template #[item]="data" v-for="item in Object.keys(omit($slots, 'default'))">
|
|
<slot :name="item" v-bind="data || {}"></slot>
|
|
</template>
|
|
</Modal>
|
|
</template>
|
|
<script lang="ts" setup>
|
|
import { getCurrentInstance, ref, nextTick, unref, computed, useAttrs } from 'vue';
|
|
import { basicProps } from './props';
|
|
import startDrag from '@/utils/Drag';
|
|
import { deepMerge } from '@/utils';
|
|
import Modal from './components/Modal';
|
|
import { ModalMethods } from './type';
|
|
import { omit, uniqueId } from 'lodash-es';
|
|
import { FullscreenExitOutlined, FullscreenOutlined, CloseOutlined } from '@ant-design/icons-vue';
|
|
|
|
const attrs = useAttrs();
|
|
const props = defineProps({ ...basicProps });
|
|
const emit = defineEmits(['cancel', 'ok', 'register']);
|
|
|
|
const propsRef = ref({});
|
|
const isModal = ref(false);
|
|
const fullScreenRef = ref(false);
|
|
const subLoading = ref(false);
|
|
|
|
const basicModalId = uniqueId('basic-modal-');
|
|
const basicModalBarId = uniqueId('basic-modal-bar-');
|
|
|
|
const getProps = computed(() => {
|
|
return { ...props, ...(unref(propsRef) as any) };
|
|
});
|
|
|
|
async function setProps(modalProps): Promise<void> {
|
|
propsRef.value = deepMerge(unref(propsRef) || ({} as any), modalProps);
|
|
}
|
|
|
|
const getWrapClassName = computed(() => {
|
|
const wrapClassName = props.wrapClassName;
|
|
return unref(fullScreenRef)
|
|
? `fullscreen-modal ${wrapClassName}`
|
|
: `basic-modal ${wrapClassName}`;
|
|
});
|
|
|
|
const getBindValue = computed(() => {
|
|
return {
|
|
...attrs,
|
|
...unref(getProps),
|
|
...unref(propsRef),
|
|
visible: unref(isModal),
|
|
wrapClassName: unref(getWrapClassName),
|
|
};
|
|
});
|
|
|
|
function setSubLoading(status: boolean) {
|
|
subLoading.value = status;
|
|
}
|
|
|
|
function openModal() {
|
|
isModal.value = true;
|
|
if (!unref(getProps).isDraggable) return;
|
|
nextTick(() => {
|
|
const oBox = document.getElementById(basicModalId);
|
|
const oBar = document.getElementById(basicModalBarId);
|
|
if (!oBox || !oBar) {
|
|
console.warn('not found modal');
|
|
return;
|
|
}
|
|
startDrag(oBar, { target: oBox });
|
|
});
|
|
}
|
|
|
|
function closeModal() {
|
|
isModal.value = false;
|
|
subLoading.value = false;
|
|
emit('cancel');
|
|
}
|
|
|
|
function handleSubmit() {
|
|
subLoading.value = true;
|
|
emit('ok');
|
|
}
|
|
|
|
function handleCancel(e) {
|
|
isModal.value = false;
|
|
emit('cancel', e);
|
|
}
|
|
|
|
function handleFullScreen(e: Event) {
|
|
e && e.stopPropagation();
|
|
fullScreenRef.value = !unref(fullScreenRef);
|
|
}
|
|
|
|
const modalMethods: ModalMethods = {
|
|
setProps,
|
|
openModal,
|
|
closeModal,
|
|
setSubLoading,
|
|
};
|
|
|
|
const instance = getCurrentInstance();
|
|
if (instance) {
|
|
emit('register', modalMethods);
|
|
}
|
|
|
|
defineExpose({
|
|
openModal,
|
|
closeModal,
|
|
setProps,
|
|
setSubLoading,
|
|
handleSubmit,
|
|
});
|
|
</script>
|
|
|
|
<style lang="less" scoped>
|
|
.cursor-move {
|
|
cursor: move;
|
|
}
|
|
.basicModal :deep(.ant-modal .ant-modal-content .ant-modal-close .ant-modal-close-x) {
|
|
width: auto;
|
|
}
|
|
</style>
|