当前位置:首页 > VUE

vue 原生实现拖拽

2026-03-29 09:05:11VUE

Vue 原生实现拖拽功能

在 Vue 中实现拖拽功能可以通过原生 HTML5 的拖拽 API 结合 Vue 的事件绑定来完成。以下是具体实现方法:

基础拖拽实现

HTML 结构

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

  <div 
    class="drop-zone"
    @dragover.prevent
    @dragenter.prevent
    @drop="handleDrop"
  >
    放置区域
  </div>
</template>

JavaScript 逻辑

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

CSS 样式

.draggable-item {
  width: 100px;
  height: 100px;
  background: #42b983;
  cursor: move;
}

.drop-zone {
  width: 300px;
  height: 300px;
  border: 2px dashed #ccc;
}

.dragging {
  opacity: 0.5;
}

列表排序拖拽

对于列表项的拖拽排序,可以结合 v-for 和数组操作:

模板部分

<template>
  <ul>
    <li 
      v-for="(item, index) in list" 
      :key="item.id"
      draggable="true"
      @dragstart="handleDragStart($event, index)"
      @dragover.prevent
      @dragenter="handleDragEnter($event, index)"
      @drop="handleDrop($event, index)"
    >
      {{ item.text }}
    </li>
  </ul>
</template>

脚本部分

<script>
export default {
  data() {
    return {
      list: [
        { id: 1, text: '项目1' },
        { id: 2, text: '项目2' },
        { id: 3, text: '项目3' }
      ],
      draggedIndex: null
    }
  },
  methods: {
    handleDragStart(e, index) {
      this.draggedIndex = index
      e.dataTransfer.effectAllowed = 'move'
    },
    handleDragEnter(e, index) {
      e.dataTransfer.dropEffect = 'move'
    },
    handleDrop(e, dropIndex) {
      if (this.draggedIndex !== null) {
        const item = this.list.splice(this.draggedIndex, 1)[0]
        this.list.splice(dropIndex, 0, item)
        this.draggedIndex = null
      }
    }
  }
}
</script>

跨组件拖拽

对于跨组件拖拽,可以使用 Vue 的 provide/inject 或全局状态管理:

父组件

provide() {
  return {
    dragState: reactive({
      draggedItem: null,
      dropTarget: null
    })
  }
}

子组件

vue 原生实现拖拽

inject: ['dragState'],
methods: {
  startDrag(item) {
    this.dragState.draggedItem = item
  },
  handleDrop() {
    if (this.dragState.draggedItem) {
      // 处理拖拽逻辑
    }
  }
}

性能优化建议

  • 使用 requestAnimationFrame 优化拖拽动画
  • 对于大型列表,使用虚拟滚动技术
  • 减少拖拽过程中的 DOM 操作
  • 使用 CSS transform 代替 top/left 定位

以上方法提供了 Vue 中原生实现拖拽功能的不同场景解决方案,可以根据具体需求选择适合的方式。

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

相关文章

vue弹幕实现不重叠

vue弹幕实现不重叠

实现 Vue 弹幕不重叠的方法 CSS 定位与动画控制 通过绝对定位和动态计算弹幕轨道高度,确保弹幕在不同轨道上运行。每条弹幕占据固定高度的轨道,避免重叠。 // 弹幕轨道高度计算 const tr…

vue 实现菜单

vue 实现菜单

Vue 实现菜单的方法 使用 Vue 实现菜单可以通过多种方式,以下是几种常见的方法: 使用 Vue Router 实现动态路由菜单 通过 Vue Router 可以动态生成菜单,根据路由配置自动渲…

vue实现cs

vue实现cs

Vue 实现 CS(Client-Side)渲染的常见方法 Vue.js 是一个用于构建用户界面的渐进式框架,默认采用客户端渲染(CSR)。以下是几种常见的实现方式: 使用 Vue CLI 创建项目…

vue实现筛选

vue实现筛选

实现筛选功能的基本思路 在Vue中实现筛选功能通常需要结合数据绑定、计算属性和方法。筛选的核心逻辑是根据用户输入的条件过滤原始数据列表,并动态更新显示结果。 数据准备 定义一个数组存储原始数据,另一…

vue实现卡片

vue实现卡片

Vue 实现卡片组件的方法 使用 Vue 实现卡片组件可以通过多种方式完成,以下是几种常见的实现方法: 使用原生 HTML 和 CSS 在 Vue 单文件组件中,可以通过模板和样式直接实现卡片效果…

vue如何实现mvvm

vue如何实现mvvm

Vue 实现 MVVM 的核心机制 Vue 的 MVVM(Model-View-ViewModel)实现依赖于数据绑定和响应式系统,通过以下核心机制完成: 数据劫持(响应式系统) Vue 使用 Ob…