当前位置:首页 > VUE

vue实现可拖动

2026-02-20 00:23:58VUE

Vue 实现可拖动功能的方法

使用 HTML5 原生拖拽 API

Vue 可以结合 HTML5 的拖拽 API 实现元素拖动功能。主要通过 draggable 属性、dragstartdragend 等事件实现。

<template>
  <div
    draggable="true"
    @dragstart="handleDragStart"
    @dragend="handleDragEnd"
    class="draggable-item"
  >
    可拖动元素
  </div>
</template>

<script>
export default {
  methods: {
    handleDragStart(e) {
      e.dataTransfer.setData('text/plain', e.target.id);
      e.target.style.opacity = '0.5';
    },
    handleDragEnd(e) {
      e.target.style.opacity = '1';
    }
  }
};
</script>

使用第三方库 vue-draggable

vue-draggable 是基于 Sortable.js 的 Vue 组件,适合列表排序和拖动场景。

安装:

npm install vuedraggable

使用示例:

vue实现可拖动

<template>
  <draggable v-model="list" @end="onDragEnd">
    <div v-for="item in list" :key="item.id">
      {{ item.name }}
    </div>
  </draggable>
</template>

<script>
import draggable from 'vuedraggable';

export default {
  components: { draggable },
  data() {
    return {
      list: [
        { id: 1, name: 'Item 1' },
        { id: 2, name: 'Item 2' }
      ]
    };
  },
  methods: {
    onDragEnd() {
      console.log('拖动结束', this.list);
    }
  }
};
</script>

自定义拖动实现

对于更复杂的拖动需求,可以监听鼠标事件实现自定义拖动逻辑。

<template>
  <div
    ref="draggable"
    class="draggable-item"
    @mousedown="startDrag"
  >
    自定义拖动元素
  </div>
</template>

<script>
export default {
  data() {
    return {
      isDragging: false,
      startX: 0,
      startY: 0,
      offsetX: 0,
      offsetY: 0
    };
  },
  methods: {
    startDrag(e) {
      this.isDragging = true;
      this.startX = e.clientX;
      this.startY = e.clientY;
      document.addEventListener('mousemove', this.onDrag);
      document.addEventListener('mouseup', this.stopDrag);
    },
    onDrag(e) {
      if (!this.isDragging) return;
      this.offsetX = e.clientX - this.startX;
      this.offsetY = e.clientY - this.startY;
      this.$refs.draggable.style.transform = `translate(${this.offsetX}px, ${this.offsetY}px)`;
    },
    stopDrag() {
      this.isDragging = false;
      document.removeEventListener('mousemove', this.onDrag);
      document.removeEventListener('mouseup', this.stopDrag);
    }
  }
};
</script>

使用 Vue 指令实现拖动

可以创建自定义指令实现可重用拖动功能。

Vue.directive('drag', {
  bind(el, binding) {
    let isDragging = false;
    let startX, startY, offsetX = 0, offsetY = 0;

    el.addEventListener('mousedown', (e) => {
      isDragging = true;
      startX = e.clientX;
      startY = e.clientY;
      document.addEventListener('mousemove', onDrag);
      document.addEventListener('mouseup', onDragEnd);
    });

    function onDrag(e) {
      if (!isDragging) return;
      offsetX = e.clientX - startX;
      offsetY = e.clientY - startY;
      el.style.transform = `translate(${offsetX}px, ${offsetY}px)`;
    }

    function onDragEnd() {
      isDragging = false;
      document.removeEventListener('mousemove', onDrag);
      document.removeEventListener('mouseup', onDragEnd);
    }
  }
});

使用指令:

vue实现可拖动

<div v-drag class="draggable-item">通过指令实现拖动</div>

拖动边界限制

对于自定义拖动实现,可以添加边界限制防止元素被拖出可视区域。

onDrag(e) {
  if (!this.isDragging) return;

  const maxX = window.innerWidth - this.$refs.draggable.offsetWidth;
  const maxY = window.innerHeight - this.$refs.draggable.offsetHeight;

  this.offsetX = Math.min(maxX, Math.max(0, e.clientX - this.startX));
  this.offsetY = Math.min(maxY, Math.max(0, e.clientY - this.startY));

  this.$refs.draggable.style.transform = `translate(${this.offsetX}px, ${this.offsetY}px)`;
}

触摸屏支持

为支持移动设备,需要添加触摸事件处理。

startDrag(e) {
  const clientX = e.clientX || e.touches[0].clientX;
  const clientY = e.clientY || e.touches[0].clientY;

  this.isDragging = true;
  this.startX = clientX;
  this.startY = clientY;

  document.addEventListener('mousemove', this.onDrag);
  document.addEventListener('touchmove', this.onDrag);
  document.addEventListener('mouseup', this.stopDrag);
  document.addEventListener('touchend', this.stopDrag);
}

性能优化

对于频繁的拖动操作,使用 CSS transform 代替 top/left 修改位置可以获得更好的性能。

this.$refs.draggable.style.transform = `translate(${this.offsetX}px, ${this.offsetY}px)`;

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

相关文章

vue实现单据

vue实现单据

Vue 实现单据功能的方法 使用 Vue 实现单据功能通常涉及表单设计、数据绑定、验证和提交等环节。以下是具体实现方案: 表单设计与数据绑定 使用 Vue 的 v-model 指令实现表单数据的双向…

vue翻页实现

vue翻页实现

Vue翻页实现方法 基础分页组件实现 使用v-for和计算属性实现基础分页逻辑: <template> <div> <ul> <l…

vue 实现工具

vue 实现工具

Vue 实现工具的方法 使用 Vue 实现工具功能可以通过多种方式完成,具体取决于工具的类型和需求。以下是几种常见的方法: 组件化实现 创建一个独立的 Vue 组件来封装工具功能。例如,实现一个计…

vue实现webapp

vue实现webapp

Vue 实现 WebApp 的基本步骤 环境准备 确保已安装 Node.js 和 npm/yarn。通过 Vue CLI 或 Vite 创建项目: npm install -g @vue/cli v…

vue实现链接

vue实现链接

Vue 实现链接的方法 在 Vue 中实现链接可以通过多种方式,包括使用 <router-link>、<a> 标签或编程式导航。以下是几种常见的方法: 使用 <rou…

vue实现京东

vue实现京东

Vue 实现京东电商网站的关键步骤 项目搭建与基础配置 使用 Vue CLI 或 Vite 初始化项目,安装 Vue Router 管理路由,Vuex/Pinia 管理状态。配置基础 UI 框架如 E…