当前位置:首页 > 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 的响应式特性,动态调整拖拽区域的范围或限制。

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
分享给朋友:

相关文章

computed vue 实现

computed vue 实现

computed 在 Vue 中的基本用法 Vue 的 computed 属性用于声明依赖于其他数据的计算属性。当依赖的数据变化时,计算属性会自动重新计算并缓存结果。 export defaul…

vue路由实现

vue路由实现

Vue 路由实现 Vue Router 是 Vue.js 的官方路由管理器,用于构建单页面应用(SPA)。以下是 Vue Router 的基本实现步骤和核心功能。 安装 Vue Router 通过…

vue实现弹幕

vue实现弹幕

Vue 实现弹幕功能 弹幕功能通常包括动态生成、滚动显示、颜色和速度随机化等特性。以下是基于 Vue 3 的实现方法。 核心思路 使用 CSS 动画控制弹幕从右向左滚动。 动态生成弹幕数据,随机设置…

vue实现兼容

vue实现兼容

Vue 兼容性实现方案 Vue.js 的兼容性主要涉及对不同浏览器、Vue 版本以及第三方库的支持。以下是常见的兼容性解决方案: 浏览器兼容性 使用 Babel 转换 ES6+ 代码为 ES5 语…

vue实现流程转化

vue实现流程转化

Vue 实现流程转化 在 Vue 中实现流程转化通常涉及多个步骤,包括状态管理、组件通信和动态渲染。以下是几种常见的实现方法: 使用 Vuex 进行状态管理 Vuex 是 Vue 的官方状态管理库,…

vue实现全选下载

vue实现全选下载

Vue实现全选下载功能 全选下载功能通常涉及前端文件列表的多选操作和批量下载逻辑。以下是基于Vue的实现方案: 数据准备与渲染 在Vue组件中定义文件列表数据和选中状态: data() { r…