当前位置:首页 > VUE

vue实现弹窗拖拽排序

2026-02-25 05:30:50VUE

Vue 实现弹窗拖拽排序

使用 Vue.Draggable 库

安装 Vue.Draggable 库:

npm install vuedraggable

在组件中引入并使用:

<template>
  <div>
    <draggable v-model="dialogList" @end="onDragEnd">
      <div v-for="dialog in dialogList" :key="dialog.id" class="dialog-item">
        {{ dialog.title }}
      </div>
    </draggable>
  </div>
</template>

<script>
import draggable from 'vuedraggable'

export default {
  components: { draggable },
  data() {
    return {
      dialogList: [
        { id: 1, title: 'Dialog 1' },
        { id: 2, title: 'Dialog 2' },
        { id: 3, title: 'Dialog 3' }
      ]
    }
  },
  methods: {
    onDragEnd() {
      console.log('New order:', this.dialogList)
    }
  }
}
</script>

<style>
.dialog-item {
  padding: 10px;
  margin: 5px;
  background: #f0f0f0;
  cursor: move;
}
</style>

自定义拖拽实现

通过 HTML5 的拖放 API 实现:

<template>
  <div>
    <div
      v-for="dialog in dialogList"
      :key="dialog.id"
      class="dialog-item"
      draggable="true"
      @dragstart="handleDragStart($event, dialog.id)"
      @dragover.prevent
      @drop="handleDrop($event, dialog.id)"
    >
      {{ dialog.title }}
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      dialogList: [
        { id: 1, title: 'Dialog 1' },
        { id: 2, title: 'Dialog 2' },
        { id: 3, title: 'Dialog 3' }
      ],
      draggedItemId: null
    }
  },
  methods: {
    handleDragStart(event, id) {
      this.draggedItemId = id
      event.dataTransfer.effectAllowed = 'move'
    },
    handleDrop(event, targetId) {
      const draggedIndex = this.dialogList.findIndex(item => item.id === this.draggedItemId)
      const targetIndex = this.dialogList.findIndex(item => item.id === targetId)

      if (draggedIndex !== -1 && targetIndex !== -1) {
        const newList = [...this.dialogList]
        const [removed] = newList.splice(draggedIndex, 1)
        newList.splice(targetIndex, 0, removed)
        this.dialogList = newList
      }
    }
  }
}
</script>

结合弹窗组件实现

在弹窗组件中添加拖拽功能:

<template>
  <div>
    <button @click="showDialog = true">Show Dialog</button>

    <div v-if="showDialog" class="dialog-wrapper" ref="dialog">
      <div class="dialog-header" @mousedown="startDrag">
        Drag Me
        <button @click="showDialog = false">Close</button>
      </div>
      <div class="dialog-content">
        Dialog Content
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      showDialog: false,
      isDragging: false,
      startX: 0,
      startY: 0,
      startLeft: 0,
      startTop: 0
    }
  },
  methods: {
    startDrag(e) {
      this.isDragging = true
      this.startX = e.clientX
      this.startY = e.clientY
      const dialog = this.$refs.dialog
      this.startLeft = dialog.offsetLeft
      this.startTop = dialog.offsetTop

      document.addEventListener('mousemove', this.handleDrag)
      document.addEventListener('mouseup', this.stopDrag)
    },
    handleDrag(e) {
      if (!this.isDragging) return
      const dialog = this.$refs.dialog
      const dx = e.clientX - this.startX
      const dy = e.clientY - this.startY
      dialog.style.left = `${this.startLeft + dx}px`
      dialog.style.top = `${this.startTop + dy}px`
    },
    stopDrag() {
      this.isDragging = false
      document.removeEventListener('mousemove', this.handleDrag)
      document.removeEventListener('mouseup', this.stopDrag)
    }
  }
}
</script>

<style>
.dialog-wrapper {
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 300px;
  border: 1px solid #ccc;
  background: white;
  z-index: 1000;
}

.dialog-header {
  padding: 10px;
  background: #f0f0f0;
  cursor: move;
  display: flex;
  justify-content: space-between;
}

.dialog-content {
  padding: 15px;
}
</style>

注意事项

确保拖拽元素设置了正确的 CSS 定位属性(如 position: absolute 或 position: fixed)

对于复杂的拖拽场景,考虑使用第三方库如 interact.js 或 sortablejs

移动端支持需要额外处理 touch 事件

拖拽性能优化:对于大量元素,使用虚拟滚动等技术

vue实现弹窗拖拽排序

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

相关文章

jquery实现vue

jquery实现vue

jQuery 和 Vue.js 是两种不同理念的前端工具,jQuery 以 DOM 操作和事件驱动为核心,而 Vue.js 是数据驱动的现代化框架。如果想用 jQuery 实现类似 Vue 的功能(如…

vue实现表白

vue实现表白

Vue 实现表白页面 使用 Vue 可以快速创建一个动态、交互式的表白页面。以下是一个简单的实现方案: 基础结构 创建一个 Vue 项目或单文件组件,包含以下核心部分: <template&…

vue代理实现

vue代理实现

Vue 代理实现方法 在 Vue 项目中,配置代理可以解决开发环境下的跨域问题,通常通过修改 vue.config.js 文件实现。以下是几种常见的代理配置方式: 基础代理配置 在 vue.con…

vue 实现流程

vue 实现流程

Vue 实现流程 Vue.js 是一个渐进式 JavaScript 框架,用于构建用户界面。以下是 Vue 实现的基本流程: 安装 Vue.js 通过 CDN 引入或使用 npm/yarn 安装:…

实现vue cli

实现vue cli

安装 Vue CLI 确保系统中已安装 Node.js(版本建议 12.x 或更高)。通过 npm 全局安装 Vue CLI: npm install -g @vue/cli 安装完成后验证版本:…

vue 实现滑动

vue 实现滑动

Vue 实现滑动效果的方法 在Vue中实现滑动效果可以通过多种方式,以下是几种常见的方法: 使用CSS过渡和动画 通过Vue的<transition>组件结合CSS过渡或动画实现滑动效…