vuedraggable-拖拽插件使用小计

1、安装插件

Vue2

npm i vuedraggable@2 # 或 yarn add vuedraggable

Vue3(官方仓库改名 vue.draggable.next)

npm i vuedraggable@next # 或 yarn add vuedraggable@next

CDN(测试用)
cdn.jsdelivr.net/npm/vuedrag...
cdn.jsdelivr.net/npm/vuedrag...

2、注册组件

全局注册(main.js)

import draggable from 'vuedraggable' // Vue3 把包名改成 'vuedraggable-next'

app.component('draggable', draggable)

局部注册

import draggable from 'vuedraggable'

export default { components:{ draggable } }

3、最小可运行示例

Vue2 写法

js 复制代码
<template>
  <draggable v-model="list" class="drag-area">
    <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:'A'},{id:2,name:'B'}] } }
}
</script>

Vue3 写法(必须具名插槽 item,且只能一个根节点)

vue 复制代码
<template>
  <draggable v-model="list" item-key="id">
    <template #item="{ element }">
      <div class="drag-area__item">{{ element.name }}</div>
    </template>
  </draggable>
</template>

<script setup>
import draggable from 'vuedraggable-next'
import { reactive } from 'vue'
const list = reactive([ {id:1,name:'A'}, {id:2,name:'B'} ])
</script>

4、核心 Props 详解

属性 类型 默认值 说明
v-model / list Array [] 与视图同步的数据源;list 与 v-model 不可同时出现
item-key String Vue3 必填,提供列表 key
tag String 'div' 容器节点名
handle String '' 仅当匹配选择器时才允许拖动,如 handle=".drag-handle"
group String / Object '' 跨列表拖拽,如 group="shared" 或 :group="{name:'shared', pull:'clone', put:true}"
animation Number 150 排序动画时长(ms)
ghost-class String 'sortable-ghost' 占位元素样式
drag-class String 'sortable-drag' 正在拖拽元素样式
filter String '' 禁止拖动的选择器
disabled Boolean false 禁用拖拽
move Function null 返回 false 取消本次拖动
clone Function original=>original 跨列表 pull='clone' 时,控制克隆逻辑

5、事件

事件名 回调形参 触发时机
@start evt 开始拖动
@end evt 拖动结束
@change evt 列表数据发生 add / remove / move 时触发
@add evt 接收外部元素
@remove evt 元素被拖到其他列表
@update evt 同列表内部排序
@choose / unchoose evt 选中/取消选中

6、多列表互相拖拽

A、B两个列表可互相拖入,支持克隆:

vue 复制代码
<template>
  <div class="lists">
    <!-- 列表 A -->
    <draggable
      v-model="listA"
      :group="{ name:'shared', pull:'clone', put:true }"
      :clone="deepClone"
    >
      <template #item="{ element }"><div>{{ element.name }}</div></template>
    </draggable>

    <!-- 列表 B -->
    <draggable
      v-model="listB"
      group="shared"
    >
      <template #item="{ element }"><div>{{ element.name }}</div></template>
    </draggable>
  </div>
</template>

<script setup>
import { reactive } from 'vue'
import draggable from 'vuedraggable-next'
const listA = reactive([{id:1, name:'a'}])
const listB = reactive([])
const deepClone = (o) => JSON.parse(JSON.stringify(o))
</script>

注意点:

  • group 的 name 必须相同;
  • 数据结构一致;
  • 数组必须是响应式(Vue2 用 Vue.observable / Vue3 用 reactive、ref)。

7、插槽用法

插槽名 作用域 说明
default - 整个容器内容,可放置不可拖动的 header/footer
item { element, index } Vue3 唯一必填插槽,渲染每一个可拖拽节点
header/footer - 固定区域,不会参与拖拽

示例:在列表顶部增加不可拖动的「添加按钮」

vue 复制代码
<draggable v-model="list">
  <template #header>
    <button @click="add">+ Add</button>
  </template>
  <template #item="{ element }">
    <div>{{ element.name }}</div>
  </template>
</draggable>

8、与UI库混合使用

Element Plus / Ant Design Vue 的表格、卡片、步骤条等均可被 draggable 包裹:

vue 复制代码
<draggable v-model="tableData" item-key="id">
  <template #item="{ element }">
    <el-card>{{ element.title }}</el-card>
  </template>
</draggable>

9、常见问题

  • Vue3 报错 "item slot required" → 使用具名插槽 #item
  • 拖动后视图未更新 → 确认数组是响应式 & key 唯一。
  • 两个列表无法互相拖 → group name 不一致或数据结构不同。
  • 想拖拽表格行 → 使用 <tr> 作为根节点即可(需设置 tag="tbody")。

10、在线资源/官方仓库

官方 Sortable.js 配置表(拖拽行为全部继承):github.com/SortableJS/...

相关推荐
盛夏绽放3 小时前
jQuery 知识点复习总览
前端·javascript·jquery
胡gh5 小时前
依旧性能优化,如何在浅比较上做文章,memo 满天飞,谁在裸奔?
前端·react.js·面试
大怪v5 小时前
超赞👍!优秀前端佬的电子布洛芬技术网站!
前端·javascript·vue.js
胡gh5 小时前
你一般用哪些状态管理库?别担心,Zustand和Redux就能说个10分钟
前端·面试·node.js
roamingcode6 小时前
Claude Code NPM 包发布命令
前端·npm·node.js·claude·自定义指令·claude code
码哥DFS6 小时前
NPM模块化总结
前端·javascript
灵感__idea7 小时前
JavaScript高级程序设计(第5版):代码整洁之道
前端·javascript·程序员
唐璜Taro7 小时前
electron进程间通信-IPC通信注册机制
前端·javascript·electron
陪我一起学编程8 小时前
创建Vue项目的不同方式及项目规范化配置
前端·javascript·vue.js·git·elementui·axios·企业规范
LinXunFeng9 小时前
Flutter - 详情页初始锚点与优化
前端·flutter·开源