当前位置:首页 > VUE

vue实现左右拖拽

2026-01-17 19:56:34VUE

Vue 实现左右拖拽功能

使用 HTML5 拖放 API

在 Vue 中可以利用 HTML5 的原生拖放 API 实现左右拖拽功能。通过 draggable 属性标记可拖拽元素,并监听 dragstartdragenddrop 事件。

<template>
  <div class="container">
    <div 
      class="draggable-item" 
      draggable="true"
      @dragstart="handleDragStart"
      @dragend="handleDragEnd"
    >
      可拖拽元素
    </div>
    <div 
      class="drop-zone"
      @dragover.prevent
      @drop="handleDrop"
    >
      放置区域
    </div>
  </div>
</template>

<script>
export default {
  methods: {
    handleDragStart(event) {
      event.dataTransfer.setData('text/plain', event.target.id);
    },
    handleDrop(event) {
      event.preventDefault();
      const data = event.dataTransfer.getData('text/plain');
      const draggedElement = document.getElementById(data);
      event.target.appendChild(draggedElement);
    },
    handleDragEnd() {
      // 拖拽结束后的逻辑
    }
  }
};
</script>

<style>
.draggable-item {
  width: 100px;
  height: 100px;
  background-color: #f0f0f0;
  cursor: move;
}
.drop-zone {
  width: 200px;
  height: 200px;
  border: 2px dashed #ccc;
}
</style>

使用第三方库(如 Vue.Draggable)

Vue.Draggable 是一个基于 Sortable.js 的 Vue 拖拽组件库,适用于更复杂的拖拽场景。

安装 Vue.Draggable:

npm install vuedraggable

实现左右拖拽:

<template>
  <div class="container">
    <draggable 
      v-model="leftItems" 
      group="items" 
      class="left-container"
    >
      <div v-for="item in leftItems" :key="item.id" class="item">
        {{ item.name }}
      </div>
    </draggable>
    <draggable 
      v-model="rightItems" 
      group="items" 
      class="right-container"
    >
      <div v-for="item in rightItems" :key="item.id" class="item">
        {{ item.name }}
      </div>
    </draggable>
  </div>
</template>

<script>
import draggable from 'vuedraggable';
export default {
  components: { draggable },
  data() {
    return {
      leftItems: [
        { id: 1, name: 'Item 1' },
        { id: 2, name: 'Item 2' }
      ],
      rightItems: [
        { id: 3, name: 'Item 3' },
        { id: 4, name: 'Item 4' }
      ]
    };
  }
};
</script>

<style>
.container {
  display: flex;
}
.left-container, .right-container {
  width: 200px;
  min-height: 300px;
  border: 1px solid #ddd;
  padding: 10px;
  margin: 10px;
}
.item {
  padding: 8px;
  margin: 5px;
  background-color: #f9f9f9;
  cursor: move;
}
</style>

自定义拖拽逻辑

如果需要完全自定义拖拽行为,可以通过鼠标事件(mousedownmousemovemouseup)实现。

<template>
  <div 
    class="draggable-element"
    :style="{ left: position.x + 'px', top: position.y + 'px' }"
    @mousedown="startDrag"
  >
    拖拽我
  </div>
</template>

<script>
export default {
  data() {
    return {
      position: { x: 0, y: 0 },
      isDragging: false,
      startPos: { x: 0, y: 0 }
    };
  },
  methods: {
    startDrag(event) {
      this.isDragging = true;
      this.startPos = {
        x: event.clientX - this.position.x,
        y: event.clientY - this.position.y
      };
      document.addEventListener('mousemove', this.drag);
      document.addEventListener('mouseup', this.stopDrag);
    },
    drag(event) {
      if (!this.isDragging) return;
      this.position = {
        x: event.clientX - this.startPos.x,
        y: event.clientY - this.startPos.y
      };
    },
    stopDrag() {
      this.isDragging = false;
      document.removeEventListener('mousemove', this.drag);
      document.removeEventListener('mouseup', this.stopDrag);
    }
  }
};
</script>

<style>
.draggable-element {
  position: absolute;
  width: 100px;
  height: 100px;
  background-color: #f0f0f0;
  cursor: move;
  user-select: none;
}
</style>

响应式拖拽区域

结合 Vue 的响应式特性,动态调整拖拽区域的范围或限制。

<template>
  <div class="drag-boundary">
    <div 
      class="draggable-box"
      :style="{ left: clampX(boxPosition.x) + 'px', top: clampY(boxPosition.y) + 'px' }"
      @mousedown="startBoxDrag"
    >
      限制范围内的拖拽
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      boxPosition: { x: 0, y: 0 },
      boundary: { width: 400, height: 400 },
      boxSize: { width: 80, height: 80 }
    };
  },
  methods: {
    startBoxDrag(event) {
      const startX = event.clientX - this.boxPosition.x;
      const startY = event.clientY - this.boxPosition.y;
      const moveHandler = (e) => {
        this.boxPosition = {
          x: this.clampX(e.clientX - startX),
          y: this.clampY(e.clientY - startY)
        };
      };
      const upHandler = () => {
        document.removeEventListener('mousemove', moveHandler);
        document.removeEventListener('mouseup', upHandler);
      };
      document.addEventListener('mousemove', moveHandler);
      document.addEventListener('mouseup', upHandler);
    },
    clampX(value) {
      return Math.max(0, Math.min(value, this.boundary.width - this.boxSize.width));
    },
    clampY(value) {
      return Math.max(0, Math.min(value, this.boundary.height - this.boxSize.height));
    }
  }
};
</script>

<style>
.drag-boundary {
  position: relative;
  width: 400px;
  height: 400px;
  border: 1px solid #333;
}
.draggable-box {
  position: absolute;
  width: 80px;
  height: 80px;
  background-color: #e0e0ff;
  cursor: move;
}
</style>

vue实现左右拖拽

标签: 拖拽vue
分享给朋友:

相关文章

vue公共列表的实现

vue公共列表的实现

实现 Vue 公共列表组件 公共列表组件通常用于展示重复结构的数据,例如商品列表、用户列表等。以下是一个典型的实现方式: 基础实现 创建可复用的列表组件 List.vue: <tem…

vue实现上移下移插件

vue实现上移下移插件

实现上移下移功能的 Vue 插件 在 Vue 中实现列表项的上移和下移功能,可以通过自定义指令或组件封装的方式完成。以下是两种常见实现方式: 基于数组操作的通用方法 通过操作数组索引实现元素位置交换…

vue实现计时

vue实现计时

Vue 实现计时功能 在 Vue 中实现计时功能可以通过多种方式完成,以下是几种常见的方法: 使用 setInterval 实现基础计时器 通过 setInterval 和 clearInterv…

eventbus vue实现

eventbus vue实现

EventBus 实现原理 EventBus 是一种发布/订阅模式,用于 Vue 组件间的通信。核心是通过一个中央事件总线管理事件监听和触发。 创建 EventBus 在 Vue 项目中创建一个独…

vue datepicker 实现

vue datepicker 实现

实现 Vue Datepicker 的基本方法 在 Vue 项目中实现日期选择功能,可以使用第三方库如 vue-datepicker 或 v-calendar。以下是两种常见实现方式: 安装 vue…

vue实现modal

vue实现modal

Vue 实现 Modal 弹窗组件 使用 Vue 实现 Modal 弹窗组件可以通过多种方式,包括原生 Vue 组件、第三方库或自定义指令。以下是几种常见方法: 原生 Vue 组件实现 创建一个基…