当前位置:首页 > 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

使用示例:

<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);
    }
  }
});

使用指令:

<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 修改位置可以获得更好的性能。

vue实现可拖动

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

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

相关文章

vue实现单词反转

vue实现单词反转

实现思路 在Vue中实现单词反转功能,可以通过多种方式完成。核心思路是利用JavaScript的字符串处理方法,将输入的单词或句子拆分为数组,反转数组后再拼接成字符串。 方法一:使用计算属性 通过计…

用vue实现滑动输入条

用vue实现滑动输入条

使用 Vue 实现滑动输入条 使用原生 HTML5 input range 实现 在 Vue 模板中直接使用 <input type="range">,通过 v-model 绑定数据:…

vue 实现过滤

vue 实现过滤

Vue 实现过滤的方法 在 Vue 中实现过滤功能可以通过多种方式完成,包括使用计算属性、自定义过滤器、第三方库等。以下是几种常见的实现方法: 使用计算属性进行过滤 计算属性是 Vue 中最常用的过…

vue实现menu

vue实现menu

Vue 实现 Menu 的方法 使用 Element UI 的 Menu 组件 Element UI 提供了现成的 Menu 组件,适合快速实现导航菜单。安装 Element UI 后,可以直接使用…

vue 实现图钉

vue 实现图钉

实现图钉效果的步骤 在Vue中实现图钉(固定位置)效果,可以通过CSS的position: sticky属性或监听滚动事件动态修改元素样式。以下是两种常见方法: 方法一:使用CSS的posi…

vue实现tabs

vue实现tabs

Vue实现Tabs组件的方法 使用动态组件和v-for指令 在Vue中创建Tabs组件可以通过动态组件和v-for指令实现。定义一个包含tab标题和内容的数组,使用v-for渲染tab标题,并通过点击…