<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 样式来设置拖拽元素的宽度、高度和背景颜色等。