通过mousemove判断dialog哪条边缩放,配合mousedown开启移动、尺寸修改。
dialog.ts
// element-plus 的 dialog 的拖拽方法const dialogDrag = (el: any, binding: any) => { addEventFun(); function addEventFun() { // 可视窗口的宽度 const clientWidth = document.documentElement.clientWidth // 可视窗口的高度 const clientHeight = document.documentElement.clientHeight // 弹窗的容器 const domDrag = el.parentElement.parentElement // 拖拽的div if (domDrag) { // 获取元素 const dialogDom = domDrag; const headerDom = dialogDom.getElementsByClassName('el-dialog__header')[0]; const dialogBoxDom = dialogDom.parentElement; // 初始化变量 let startX, startY, initialX, initialY, newWidth, newHeight; let isDrag = false; let dragPosition = { x: 0, y: 0, }; let isResizing : any = false; let isMousedown = false; headerDom.style.cursor = 'move'; dialogDom.style.position = 'absolute'; dialogDom.style.width = '60%'; dialogDom.style.height = '80%'; dialogDom.style.top = '10%'; dialogDom.style.left = '20%'; dialogDom.style.margin = '0'; // 鼠标移动改变指针样式 dialogDom.addEventListener('mousemove', (e: any) => { if (isMousedown) return; const size = 5; const width = dialogDom.clientWidth; const height = dialogDom.clientHeight; const dialogBoxX = e.pageX - dialogBoxDom.offsetLeft; const dialogBoxY = e.pageY - dialogBoxDom.offsetTop; startX = dialogBoxX - dialogDom.offsetLeft; startY = dialogBoxY - dialogDom.offsetTop; // console.log(width, height); if (startX < size && startY < size) { dialogDom.style.cursor = 'nw-resize'; isResizing = 'top-left'; } else if (startX > width - size && startY > height - size) { dialogDom.style.cursor = 'nw-resize'; isResizing = 'bottom-right'; } else if (startX > width - size && startY < size) { dialogDom.style.cursor = 'ne-resize'; isResizing = 'top-right'; } else if (startX < size && startY > height - size) { dialogDom.style.cursor = 'ne-resize'; isResizing = 'bottom-left'; } else if (startX < size) { dialogDom.style.cursor = 'e-resize'; isResizing = 'left'; } else if (startX > width - size) { dialogDom.style.cursor = 'e-resize'; isResizing = 'right'; } else if (startY < size) { dialogDom.style.cursor = 'n-resize'; isResizing = 'top'; } else if (startY > height - size) { dialogDom.style.cursor = 'n-resize'; isResizing = 'bottom'; } else { dialogDom.style.cursor = 'default'; isResizing = false; } }); // 拖拽 headerDom.addEventListener('mousedown', (e: any) => { isDrag = true; dragPosition.x = e.pageX - dialogBoxDom.offsetLeft - dialogDom.offsetLeft; dragPosition.y = e.pageY - dialogBoxDom.offsetTop - dialogDom.offsetTop; }); // 鼠标按下判断是否开启尺寸拖拽 dialogDom.addEventListener('mousedown', (e: any) => { if (!isResizing) return; isMousedown = true; }); // 按住鼠标移动改变尺寸 dialogDom.parentElement.addEventListener('mousemove', (e: any) => { const domWidth = dialogDom.clientWidth; const domHeight = dialogDom.clientHeight; const domTop = dialogDom.offsetTop; const domLeft = dialogDom.offsetLeft; const dialogBoxX = e.pageX - dialogBoxDom.offsetLeft; const dialogBoxY = e.pageY - dialogBoxDom.offsetTop; const minWidth = 100; const minHeight = 100; // 拖拽 if(isDrag) { // console.log(dialogDom.clientWidth) dialogDom.style.left = dialogBoxX - dragPosition.x + 'px'; dialogDom.style.top = dialogBoxY - dragPosition.y + 'px'; } if (!isMousedown) return; switch (isResizing) { case 'top-left': moveTop(); moveLeft(); break; case 'bottom-right': moveBottom(); moveRight(); break; case 'top-right': moveTop(); moveRight(); break; case 'bottom-left': moveBottom(); moveLeft(); break; case 'left': moveLeft(); break; case 'right': moveRight(); break; case 'top': moveTop(); break; case 'bottom': moveBottom(); break; default: break; } function moveLeft() { const width = domWidth + domLeft - dialogBoxX; if (domWidth < minWidth && width < domWidth) return; dialogDom.style.left = dialogBoxX + 'px'; dialogDom.style.width = width + 'px'; } function moveRight() { const width = dialogBoxX - domLeft; if (domWidth < minWidth && width < domWidth) return; dialogDom.style.width = width + 'px'; } function moveTop() { const height = domHeight + domTop - dialogBoxY; if (domHeight < minHeight && height < domHeight) return; dialogDom.style.top = dialogBoxY + 'px'; dialogDom.style.height = height + 'px'; } function moveBottom() { const height = dialogBoxY - domTop; if (domHeight < minHeight && height < domHeight) return; dialogDom.style.height = height + 'px'; } }); // 鼠标抬起 dialogDom.parentElement.addEventListener('mouseup', (e: any) => { isDrag = false; isMousedown = false; }); } else { setTimeout(() => { addEventFun(); }, 1000); } }}export default dialogDrag
main.ts
import { createApp } from 'vue'import ElementPlus from 'element-plus'import 'element-plus/dist/index.css'import dialogDrag from "./util/dialog"createApp(AppVue) .use(ElementPlus) .directive('dialogdrag', { mounted(el, binding) { dialogDrag(el, binding) } }) .mount('#app') .$nextTick(() => { postMessage({ payload: 'removeLoading' }, '*') })
demo.vue
<el-dialog v-model="addMenuShow" title="" width="50%" :append-to-body= :close-on-click-modal="false" :show-close="false"> <div v-dialogdrag>内容</div> </el-dialog>