当前位置:首页 > 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实现下拉菜单可以通过动态绑定v-show或v-if控制菜单显示隐藏,结合事件监听(如@click或@mouseenter)触发状态切换。以下是两种常见实现方式: 方…

vue实现多用户登录

vue实现多用户登录

实现多用户登录的基本思路 在Vue中实现多用户登录通常需要结合后端API完成身份验证,并通过前端路由、状态管理(如Vuex或Pinia)和本地存储(如localStorage)来管理用户会话。以下是关…

vue实现tree

vue实现tree

Vue 实现 Tree 组件 使用 Vue 实现 Tree 组件可以通过递归组件的方式来实现层级结构展示。以下是一个完整的实现方法: 基础递归组件实现 创建 Tree 组件文件 Tree.vue,使…

vue实现分栏

vue实现分栏

Vue实现分栏的常见方法 使用CSS Flexbox布局 通过Flexbox可以快速实现分栏效果,适合大多数响应式布局场景 <template> <div class="con…

vue实现换页

vue实现换页

Vue实现页面切换的方法 在Vue中实现页面切换通常可以通过Vue Router来完成。Vue Router是Vue.js官方的路由管理器,用于构建单页面应用(SPA)。以下是几种常见的实现方式:…

vue 实现上传

vue 实现上传

Vue 实现文件上传 使用 Vue 实现文件上传可以通过原生 HTML 的 <input type="file"> 或第三方库(如 axios、vue-upload-component)完…