<template> <div> <div v-draggable class="draggable">拖拽我</div> </div> </template> <script> export default { directives: { draggable: { mounted(el) { let isDragging = false; let offset = { x: 0, y: 0 }; const parentRect = el.parentNode.getBoundingClientRect(); // 获取父元素的边界信息 el.addEventListener("mousedown", handleMouseDown); document.addEventListener("mousemove", handleMouseMove); document.addEventListener("mouseup", handleMouseUp); function handleMouseDown(event) { isDragging = true; offset.x = event.offsetX; offset.y = event.offsetY; } function handleMouseMove(event) { if (!isDragging) return; const x = event.clientX - offset.x; const y = event.clientY - offset.y; const minX = 0; const minY = 0; const maxX = parentRect.width - el.offsetWidth; const maxY = parentRect.height - el.offsetHeight; const boundedX = Math.max(minX, Math.min(x, maxX)); const boundedY = Math.max(minY, Math.min(y, maxY)); el.style.left = boundedX + "px"; el.style.top = boundedY + "px"; } function handleMouseUp() { isDragging = false; } }, }, }, }; </script> <style> .draggable { position: absolute; left: 0; top: 0; background-color: lightblue; width: 100px; height: 100px; cursor: move; } </style>
在上述示例中,相对于Vue 实现一个拖拽功能(指令)我们做了以下更改:
- 使用
getBoundingClientRect()
获取父元素的边界信息,以便限制拖拽范围。 - 将
mousemove
和mouseup
事件监听器绑定到document
对象上,以确保在鼠标移出拖拽元素时仍能正常工作。 - 添加了边界检测逻辑,通过比较拖拽元素的位置与父元素边界来限制其范围。将拖拽元素的左边界限制在
[0, parentWidth - elWidth]
范围内,将上边界限制在[0, parentHeight - elHeight]
范围内。
请确保为拖拽元素添加 position: absolute;
样式,以便使其位置属性生效,并使用合适的 CSS 样式来设置拖拽元素的宽度、高度和背景颜色等。