这里提供一个简单的实现思路,具体代码可以根据需求进行修改。

HTML结构:

<div id="app">
  <div class="container">
    <div class="item" v-for="item in items" :key="item.id" 
         :style="{left: item.left + 'px', top: item.top + 'px'}"
         @mousedown="startDrag(item.id, $event)">
        <img :src="item.src" @dragstart="false">
    </div>
  </div>
</div>

CSS样式:

.container {
  position: relative;
  width: 600px;
  height: 600px;
  margin: 20px auto;
  border: 1px solid #ccc;
}

.item {
  position: absolute;
  width: 200px;
  height: 200px;
  border: 1px solid #ccc;
  cursor: move;
}

JS代码:

new Vue({
  el: '#app',
  data: {
    items: [
      { id: 1, src: 'https://picsum.photos/id/1/200/200', left: 0, top: 0 },
      { id: 2, src: 'https://picsum.photos/id/2/200/200', left: 200, top: 0 },
      { id: 3, src: 'https://picsum.photos/id/3/200/200', left: 400, top: 0 },
      { id: 4, src: 'https://picsum.photos/id/4/200/200', left: 0, top: 200 },
      { id: 5, src: 'https://picsum.photos/id/5/200/200', left: 200, top: 200 },
      { id: 6, src: 'https://picsum.photos/id/6/200/200', left: 400, top: 200 },
      { id: 7, src: 'https://picsum.photos/id/7/200/200', left: 0, top: 400 },
      { id: 8, src: 'https://picsum.photos/id/8/200/200', left: 200, top: 400 },
      { id: 9, src: 'https://picsum.photos/id/9/200/200', left: 400, top: 400 }
    ],
    dragging: false,
    dragItem: null,
    startX: 0,
    startY: 0,
    offsetX: 0,
    offsetY: 0
  },
  methods: {
    startDrag(id, event) {
      this.dragging = true;
      this.dragItem = this.items.find(item => item.id === id);
      this.startX = event.clientX;
      this.startY = event.clientY;
      this.offsetX = this.dragItem.left - this.startX;
      this.offsetY = this.dragItem.top - this.startY;
    },
    endDrag() {
      this.dragging = false;
      this.dragItem = null;
    },
    handleMouseMove(event) {
      if (this.dragging && this.dragItem) {
        const x = event.clientX + this.offsetX;
        const y = event.clientY + this.offsetY;
        this.dragItem.left = x;
        this.dragItem.top = y;
      }
    }
  },
  mounted() {
    document.addEventListener('mouseup', this.endDrag);
    document.addEventListener('mousemove', this.handleMouseMove);
  },
  beforeDestroy() {
    document.removeEventListener('mouseup', this.endDrag);
    document.removeEventListener('mousemove', this.handleMouseMove);
  }
});

在上面的代码中,首先定义了一个包含图片信息的数组 items,每个图片都包含 idsrclefttop 四个属性。其中 lefttop 分别表示图片的位置。

在 HTML 中,使用 v-for 循环渲染出所有的图片,并且绑定了 @mousedown 事件,用来开始拖拽操作。同时,为了防止图片在拖拽时自动生成 ghost image,需要在 img 标签上添加 @dragstart="false" 属性。

在 JS 中,定义了几个变量用来保存拖拽相关的信息。 dragging 表示是否正在拖拽,dragItem 表示当前正在拖拽的图片,startXstartY 表示鼠标按下时的位置,offsetXoffsetY 表示鼠标相对于拖拽图片左上角的偏移量。

接下来定义了三个方法。 startDrag 方法用来开始拖拽操作,当鼠标按下时将 dragging 置为 true,并且将 dragItem 设置为当前拖拽的图片。同时记录下鼠标按下时的位置和拖拽图片的偏移量。

endDrag 方法用来结束拖拽操作,将 draggingdragItem 置为 falsenull

handleMouseMove 方法用来处理鼠标移动事件,当 draggingdragItem 都为 true 时,计算出拖拽图片的新位置,并更新 lefttop 属性。

最后在 mounted 钩子中监听 mouseupmousemove 事件,当拖拽结束时调用 endDrag 方法,当鼠标移动时调用 handleMouseMove 方法。在 beforeDestroy 钩子中移除这两个事件的监听。

用vue实现图片可以在两个区域内互相拖拽排列要整齐

原文地址: https://www.cveoy.top/t/topic/ZvZ 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录