1039 字
约 3 分钟
0
Vue Draggable Plus 入门:拖拽排序最佳实践

Vue Draggable Plus 入门:拖拽排序最佳实践

待办列表拖一下换位置、后台菜单拖一下调顺序——这类交互用户已经默认「就该有」。Vue Draggable Plus 让它变成三行代码。

它是什么

Vue Draggable Plus 是 Vue 3 的拖拽排序组件库,基于原生 HTML5 Drag and Drop API 实现(底层用了 SortableJS 的成熟方案),提供两种用法:组件包裹式(VueDraggable)和组合式函数式(useDraggable)。

它解决的痛点:原生的拖放 API 极其底层(dragstart/dragover/drop 事件、dataTransfer 传递、防默认行为),自己实现一个「拖动重排列表」要写上百行代码还要处理各种边界。这个库把「拖动 → 目标位置计算 → 数据顺序更新」整个封装掉了。

pnpm add vue-draggable-plus

最小示例:拖动排序一个列表

组件式——直接包住要排序的元素:

<script setup>
import { ref } from 'vue';
import { VueDraggable } from 'vue-draggable-plus';

const list = ref([
  { id: 1, title: '学 Vue 3' },
  { id: 2, title: '学 Pinia' },
  { id: 3, title: '写项目' },
]);

function onUpdate() {
  // 拖动结束时 list.value 的顺序已经是新的了,直接保存即可
  saveOrder(list.value.map((item, i) => ({ id: item.id, sort: i })));
}
</script>

<template>
  <VueDraggable v-model="list" @update="onUpdate" class="task-list">
    <div v-for="item in list" :key="item.id" class="task-item">
      {{ item.title }}
    </div>
  </VueDraggable>
</template>

核心心智模型:v-model 绑定数组,拖动后数组顺序自动更新。你不需要知道拖到了第几位——数据就是真相,DOM 跟随数据。

函数式——不引入组件,给已有元素附加拖拽能力:

<script setup>
import { ref } from 'vue';
import { useDraggable } from 'vue-draggable-plus';

const list = ref([...]);
const el = ref(null);

useDraggable(el, list, { animation: 150 });
</script>

<template>
  <ul ref="el">
    <li v-for="item in list" :key="item.id">{{ item.title }}</li>
  </ul>
</template>

函数式适合「列表结构不想被组件包一层」的场景(比如表格行排序),组件式适合常规列表。两者能力一致。

常用配置

useDraggable(el, list, {
  animation: 150,        // 拖动动画时长,体验必需
  handle: '.drag-icon',  // 只允许通过把手拖动(内容区还能正常选中文字)
  filter: 'input',       // 元素内 input 不可触发拖拽
  ghostClass: 'drag-ghost',   // 拖动中占位符的样式类
  chosenClass: 'drag-chosen', // 被选中项样式
  disabled: readonly,    // 响应式开关:查看态禁拖、编辑态可拖
});

handle 值得单独说:不要让整个卡片可拖。用户想选中卡片里的文字、点卡片里的按钮,全被拖拽拦截,体验很糟。给一个显式的拖拽把手(六点图标)才是对的交互。

跨列表拖动

两个列表之间互拖(回收站还原、任务看板列间移动),把同一个 group 名配给两个 draggable 即可:

<VueDraggable v-model="todoList" group="tasks" @add="onAddTodo">
  <TaskItem v-for="t in todoList" :key="t.id" :task="t" />
</VueDraggable>

<VueDraggable v-model="doneList" group="tasks" @add="onAddDone">
  <TaskItem v-for="t in doneList" :key="t.id" :task="t" />
</VueDraggable>

@add 在元素从别的列表拖进来时触发,v-model 的数组已经包含了新成员,你要做的是同步后端(改它的状态字段)。

本站的应用

本站管理后台里 Wiki 目录排序、待办清单排序用的就是它:目录树里拖动条目调整顺序,拖完把新的顺序(id + sort 值列表)一次性提交后端。交互上配了 handle 把手 + animation: 150,拖动时有幽灵占位提示落点。

与后端配合的正确姿势

拖拽排序的前端很爽,后端要接得住。通用方案:每个条目存一个 sort 整数字段,拖完把全量顺序(或受影响区间的 id→sort 映射)提交,后端一个事务批量更新。条目量大时用间隔数值(如 1000、2000、3000)留插队余量,减少每次拖动要更新的行数。

小结

Vue Draggable Plus 把「拖拽排序」从一天的工作量压缩到三行代码,且通过 v-model 保持了「数据驱动」的 Vue 心智——你不操作 DOM,只操作数组。记住两个细节:配 handle 把手保护交互区,拖完提交 sort 让顺序持久化。

Vue Draggable Plus 入门:拖拽排序最佳实践
http://www.clxhxhhr.top/posts/3716/
作者
clxstart
发布于
2026-09-25
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。