当前位置:首页 > 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) 使用组件库(如Element UI) Element UI提供了现成的验证码组件,可直接集成到Vue项目中。 安装Element UI: npm install elem…

vue如何实现注册

vue如何实现注册

实现用户注册功能 在Vue中实现注册功能通常需要结合前端表单和后端API交互。以下是完整的实现方案: 创建注册表单组件 注册表单需要包含用户名、邮箱、密码等基本字段,并进行表单验证: <…

vue实现本地数据存储

vue实现本地数据存储

使用 localStorage 或 sessionStorage Vue 中可以直接调用浏览器提供的 localStorage 或 sessionStorage API 进行数据存储。localSto…

vue无限菜单怎么实现

vue无限菜单怎么实现

实现 Vue 无限菜单的方法 递归组件实现嵌套菜单 使用 Vue 的递归组件特性可以轻松实现无限级嵌套菜单。通过组件调用自身的方式处理嵌套数据。 <template> <ul&…

vue穿梭框组件实现

vue穿梭框组件实现

实现基础穿梭框组件 在Vue中实现穿梭框组件,可以使用<el-transfer>(Element UI)或手动实现。以下是手动实现的核心逻辑: <template> &l…

vue实现双折线图

vue实现双折线图

实现双折线图的步骤 安装必要的依赖库(如 ECharts 或 Chart.js),这里以 ECharts 为例: npm install echarts --save 在 Vue 组件中引入 ECh…