| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- <template>
- <a-modal
- ref="modalRef"
- :wrap-style="{ overflow: 'hidden' }"
- @ok="handleOk"
- @cancel="close"
- :closable="false"
- v-bind="{
- cancelText: '取消',
- okText: '确定',
- ...props
- }"
- :confirmLoading="state.confirmLoading"
- >
- <template #title>
- <div ref="modalTitleRef" style="width: 100%; cursor: move">{{props.label || 'model'}}</div>
- </template>
- <template #modalRender="{ originVNode }">
- <div :style="transformStyle">
- <component :is="originVNode" />
- </div>
- </template>
- <slot></slot>
- </a-modal>
- </template>
- <script lang="ts" setup >
- import { useDraggable } from '@vueuse/core'
- import { ModalProps } from 'ant-design-vue'
- import { ref, watch, watchEffect, computed, CSSProperties, reactive, onMounted } from 'vue'
- export interface ModalProPorps extends ModalProps {
- label: string,
- openConfirmLoading?: boolean,
- cancel?: () => void
- }
- export interface ModalOkProps {
- confirmed: () => void
- confirmStart: () => void
- }
- const emit = defineEmits<{
- (e: 'close'): void
- (e: 'ok', { confirmStart, confirmed }: ModalOkProps): void
- }>()
- const props = defineProps<ModalProPorps>()
- interface StateProps {
- confirmLoading: boolean
- }
- const state = reactive<Partial<StateProps>>({})
- const close = () => emit('close')
- const handleOk = async () => {
- console.log('modal-pro:-----ok')
- emit('ok', {
- confirmStart: () => state.confirmLoading = true,
- confirmed: () => state.confirmLoading = false
- })
- }
- // 拖拽相关的代码
- const modalTitleRef = ref()
- const { x, y, isDragging } = useDraggable(modalTitleRef)
- const startX = ref<number>(0)
- const startY = ref<number>(0)
- const startedDrag = ref(false)
- const transformX = ref(0)
- const transformY = ref(0)
- const preTransformX = ref(0)
- const preTransformY = ref(0)
- const dragRect = ref({ left: 0, right: 0, top: 0, bottom: 0 })
- watch([x, y], () => {
- if (!startedDrag.value) {
- startX.value = x.value
- startY.value = y.value
- const bodyRect = document.body.getBoundingClientRect()
- const titleRect = modalTitleRef.value.getBoundingClientRect()
- dragRect.value.right = bodyRect.width - titleRect.width
- dragRect.value.bottom = bodyRect.height - titleRect.height
- preTransformX.value = transformX.value
- preTransformY.value = transformY.value
- }
- startedDrag.value = true
- })
- watch(isDragging, () => {
- if (!isDragging) {
- startedDrag.value = false
- }
- })
- watchEffect(() => {
- if (startedDrag.value) {
- transformX.value =
- preTransformX.value +
- Math.min(Math.max(dragRect.value.left, x.value), dragRect.value.right) -
- startX.value
- transformY.value =
- preTransformY.value +
- Math.min(Math.max(dragRect.value.top, y.value), dragRect.value.bottom) -
- startY.value
- }
- })
- const transformStyle = computed<CSSProperties>(() => {
- return {
- transform: `translate(${transformX.value}px, ${transformY.value}px)`
- }
- })
- // 拖拽相关的代码
- </script>
- <style>
- </style>
|