wms-antdvue/.svn/pristine/5a/5a8cd43a9454b71a36d20b996bb85cdfaf540b84.svn-base
2024-11-07 16:33:03 +08:00

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>