Vue3使用vuedraggable实现拖拽排序

安装依赖

npm 复制代码
npm install vuedraggable@next

引入组件

vue 复制代码
import draggable from 'vuedraggable'

基础用法

vue 复制代码
<template>
    <draggable v-model="innerList" item-key="props" handle=".sort-icon" :disabled="false" :animation="300">
        <template #item="{ element }">
            <div class="flexAlign">
                <div class="sort-icon" style="margin-right: 5px;cursor: pointer;font-size: 18px;">⠿</div>
                {{ element.label }}
            </div>
        </template>
    </draggable>
</template>

<script setup>
    import draggable from 'vuedraggable';
    const innerList = ref([
        {label:"名称"}
    ])
</script>

常用属性说明

属性名 类型 说明
v-model Array 绑定数组,拖拽后自动更新顺序
item-key String 每个 item 的唯一 key
tag String 渲染的容器标签,默认div
group String/Object 分组设置,支持跨列表拖拽
disabled Boolean 是否禁用拖拽
handle String 拖拽手柄选择器
animation Number 拖拽的动画过渡时间

事件名

事件名 说明 参数
@start 拖拽开始 event
@end 拖拽完成 event
@change 列表顺序发生变化 { moved: { oldIndex, newIndex } }
@add 从别的列表添加到当前 event
@remove 当前列表被移除元素 event

实战进阶场景

拖拽手柄限制(只能通过图标拖动)

xml 复制代码
<draggable v-model="list" item-key="id" handle=".sort-icon">
  <template #item="{ element }">
    <div>
      <span class="sort-icon">⠿</span>
      {{ element.name }}
    </div>
  </template>
</draggable>

禁用某项拖动

xml 复制代码
<draggable v-model="list" item-key="id" :move="checkMove" @change="logChange">
</draggable>

<script setup>
const checkMove = (e) => {
  return !e.draggedContext.element.fixed
}
const logChange = (e) => console.log(e)
</script>

跨列表拖拽

ini 复制代码
<draggable v-model="list1" item-key="id" group="all">
  ...
</draggable>

<draggable v-model="list2" item-key="id" group="all">
  ...
</draggable>

也可以使用对象方式更灵活控制:

yaml 复制代码
group="{ name: 'all', pull: true, put: true }"

嵌套拖拽(如树形结构)

ini 复制代码
<draggable v-model="tabList" item-key="id">
  <template #item="{ element }">
    <div>{{ element.name }}</div>
    <draggable
      v-if="element.children"
      v-model="element.children"
      item-key="id"
      :group="{ name: 'all' }"
    >
      <template #item="{ element }">
        <div class="child">{{ element.name }}</div>
      </template>
    </draggable>
  </template>
</draggable>

示例:拖拽后保存顺序

xml 复制代码
<el-button @click="save">保存顺序</el-button>
<draggable v-model="list" item-key="id" @end="save" />

<script setup>
const save = () => {
  console.log('新顺序:', list.value.map(i => i.id))
}
</script>

常见问题排查

  1. 拖不动?

    • 是否设置了 item-key
    • 是否被 CSS 覆盖了事件(例如 overflow、position)
    • 是否启用了 disabled 属性
  2. 拖动异常(闪烁/跳动)?

    • 确保子项具有稳定的 key
    • 不要在拖拽中操作 DOM
  3. 样式塌陷?

    • 添加必要的 min-heightborder 保持布局正常
相关推荐
qq_589666052 小时前
TypeScript 完整入门教程
前端·javascript·typescript
用户059540174465 小时前
LLM对话记忆测试踩坑实录:手工回归30分钟,自动化后2分钟发现3个隐藏Bug
前端·css
Ashley的成长之路6 小时前
前端性能优化实战手册·第2篇:资源加载策略全解
前端·性能优化·资源加载·http/3·性能优化实战·资源加载优化
浅水壁虎6 小时前
vue基础(第二章 )
前端·javascript·vue.js
界面开发小八哥6 小时前
界面控件DevExtreme v26.1新版亮点——支持Angular 22
前端·javascript·angular.js·devexpress·ui开发·devextreme
Getflare6 小时前
前端 + UI 设计 + AI:这不是三个工种,是一个新三角能力模型(附自检清单)
前端·人工智能·ui
oil欧哟6 小时前
我做了一个 Vibe Coding 术语学习站:VibeHub
前端·ai·agent·独立开发·vibe coding
审小匠OpenCPAi7 小时前
银行流水核查怎么自动化?单边匹配、双向勾稽与图聚类异常检测的工程对比
java·前端·人工智能·python·审计
Revolution617 小时前
一个公共表格组件,是怎么一步步失控的
前端·前端工程化