Vue 实现一个拖拽功能并带边界检测(指令)

发布时间 2023-11-23 14:48:44作者: joncky
使用 Vue 的自定义指令(directive)来实现拖拽功能,并支持具有边界检测和限制拖拽范围,示例代码如下:
<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 样式来设置拖拽元素的宽度、高度和背景颜色等。