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/...

相关推荐
Fantastic_sj18 分钟前
CSS-in-JS 动态主题切换与首屏渲染优化
前端·javascript·css
鹦鹉00721 分钟前
SpringAOP实现
java·服务器·前端·spring
再学一点就睡4 小时前
手写 Promise 静态方法:从原理到实现
前端·javascript·面试
再学一点就睡4 小时前
前端必会:Promise 全解析,从原理到实战
前端·javascript·面试
前端工作日常5 小时前
我理解的eslint配置
前端·eslint
前端工作日常5 小时前
项目价值判断的核心标准
前端·程序员
90后的晨仔6 小时前
理解 Vue 的列表渲染:从传统 DOM 到响应式世界的演进
前端·vue.js
OEC小胖胖6 小时前
性能优化(一):时间分片(Time Slicing):让你的应用在高负载下“永不卡顿”的秘密
前端·javascript·性能优化·web
烛阴6 小时前
ABS - Rhomb
前端·webgl
植物系青年6 小时前
10+核心功能点!低代码平台实现不完全指南 🧭(下)
前端·低代码