vue3 + antd modal弹窗拖拽全局封装 使用useDraggable
建一个draggable.js
// draggableDirective.js
import { ref, watch, watchEffect } from 'vue';import { useDraggable } from '@vueuse/core';const draggableDirective = {mounted(el) {const { isDragging, x, y } = useDraggable(el);const startX = ref(0);const startY = ref(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 = el.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.value) {startedDrag.value = false;}});const updateTransform = () => {const modelCenter = el.closest('.ant-modal-content');modelCenter.style.transform = `translate(${transformX.value}px, ${transformY.value}px)`;};watchEffect(() => {if (startedDrag.value) {// 允许拖拽到看不见// transformX.value = preTransformX.value + x.value - startX.value;// transformY.value = preTransformY.value + y.value - startY.value;// 拖拽边靠近title时就拖拽不动了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;updateTransform();}});},
};export default draggableDirective;
在main.js中注入
使用时在modal内加入
<template #title><div style="width: 100%; cursor: move" v-draggable>采购申请</div></template>