当前位置:首页 > VUE

vue 实现拖动

2026-02-10 04:41:30VUE

Vue 实现拖动功能

使用 HTML5 原生拖放 API

在 Vue 中可以通过 HTML5 的拖放 API 实现基本的拖动功能。需要监听 dragstartdragoverdrop 事件。

<template>
  <div 
    @dragstart="handleDragStart" 
    @dragover.prevent 
    @drop="handleDrop"
    draggable="true"
  >
    拖动元素
  </div>
</template>

<script>
export default {
  methods: {
    handleDragStart(e) {
      e.dataTransfer.setData('text/plain', e.target.id)
    },
    handleDrop(e) {
      const id = e.dataTransfer.getData('text/plain')
      const draggableElement = document.getElementById(id)
      e.target.appendChild(draggableElement)
    }
  }
}
</script>

使用第三方库 vue-draggable

对于更复杂的拖动场景,推荐使用 vue-draggable 库。它基于 Sortable.js,提供了丰富的拖动功能。

安装:

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('拖动结束')
    }
  }
}
</script>

自定义拖动指令

可以创建自定义指令来实现更灵活的拖动控制。

Vue.directive('drag', {
  bind(el, binding) {
    let startX, startY, initialX, initialY

    el.style.position = 'absolute'

    el.addEventListener('mousedown', (e) => {
      startX = e.clientX
      startY = e.clientY
      initialX = el.offsetLeft
      initialY = el.offsetTop

      document.addEventListener('mousemove', move)
      document.addEventListener('mouseup', up)

      e.preventDefault()
    })

    function move(e) {
      const dx = e.clientX - startX
      const dy = e.clientY - startY

      el.style.left = initialX + dx + 'px'
      el.style.top = initialY + dy + 'px'
    }

    function up() {
      document.removeEventListener('mousemove', move)
      document.removeEventListener('mouseup', up)
    }
  }
})

拖动排序实现

结合 Vue 的响应式特性,可以实现拖动排序功能。

vue 实现拖动

<template>
  <div 
    v-for="(item, index) in items" 
    :key="item.id"
    draggable="true"
    @dragstart="dragStart(index)"
    @dragover.prevent
    @dragenter="dragEnter(index)"
    @dragend="dragEnd"
  >
    {{ item.text }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [
        { id: 1, text: 'Item 1' },
        { id: 2, text: 'Item 2' }
      ],
      draggingIndex: null
    }
  },
  methods: {
    dragStart(index) {
      this.draggingIndex = index
    },
    dragEnter(index) {
      if (this.draggingIndex !== index) {
        const temp = this.items[this.draggingIndex]
        this.$set(this.items, this.draggingIndex, this.items[index])
        this.$set(this.items, index, temp)
        this.draggingIndex = index
      }
    },
    dragEnd() {
      this.draggingIndex = null
    }
  }
}
</script>

拖动边界限制

可以通过计算限制拖动元素的移动范围。

function move(e) {
  const dx = e.clientX - startX
  const dy = e.clientY - startY

  let newX = initialX + dx
  let newY = initialY + dy

  // 限制在父容器内
  const parentRect = el.parentElement.getBoundingClientRect()
  const elRect = el.getBoundingClientRect()

  newX = Math.max(0, Math.min(newX, parentRect.width - elRect.width))
  newY = Math.max(0, Math.min(newY, parentRect.height - elRect.height))

  el.style.left = newX + 'px'
  el.style.top = newY + 'px'
}

拖动性能优化

对于大量可拖动元素,应该使用事件委托来优化性能。

mounted() {
  this.$refs.container.addEventListener('mousedown', (e) => {
    if (e.target.classList.contains('draggable')) {
      // 拖动逻辑
    }
  })
}

触摸屏支持

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

el.addEventListener('touchstart', (e) => {
  startX = e.touches[0].clientX
  startY = e.touches[0].clientY
  // 其他逻辑类似鼠标事件
})

以上方法可以根据具体需求选择使用,从简单的原生 API 到功能完善的第三方库,Vue 提供了多种实现拖动功能的方案。

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

相关文章

vue聊天实现

vue聊天实现

Vue 聊天应用实现步骤 创建 Vue 项目 使用 Vue CLI 或 Vite 初始化项目,安装必要依赖(如 Vue 3、Element UI 或 Vuetify 用于 UI 组件)。 npm c…

vue实现$.extend

vue实现$.extend

Vue 实现类似 jQuery 的 $.extend 功能 在 Vue 中实现类似 jQuery 的 $.extend 功能,可以通过多种方式完成。$.extend 主要用于合并多个对象的属性,Vue…

vue 实现关闭

vue 实现关闭

Vue 实现关闭功能的方法 在Vue中实现关闭功能通常涉及组件销毁、模态框隐藏或路由跳转等场景。以下是几种常见实现方式: 销毁当前组件 使用v-if或v-show控制组件显示/隐藏,适用于局部组件:…

vue实现打印

vue实现打印

使用Vue实现打印功能 在Vue项目中实现打印功能可以通过多种方式完成,以下是几种常见的方法: 方法一:使用window.print() 这种方法适用于打印整个页面或特定区域的内容。 // 在Vu…

react实现vue

react实现vue

React 实现 Vue 功能 React 和 Vue 是两种不同的前端框架,但可以通过一些方法在 React 中实现 Vue 的特性。以下是几种常见 Vue 功能在 React 中的实现方式: 双…

vue实现盒子平移

vue实现盒子平移

实现盒子平移的方法 在Vue中实现盒子平移可以通过CSS的transform属性结合Vue的动态绑定来完成。以下是几种常见的实现方式: 使用内联样式绑定 通过Vue的v-bind:style或简写:…