Vue3 中使用 vuedraggable 实现拖拽排序功能,分组拖拽

发布于:2025-03-27 ⋅ 阅读:(52) ⋅ 点赞:(0)

Vue3 中使用 vuedraggable 实现拖拽排序功能,分组拖拽

  1. 安装draggable
 npm install vuedraggable@next --save
  1. 基础用法示例
<template>
  <div class="app-container">
    <draggable 
      v-model="list" 
      item-key="id"
      :group="{ name: 'items' }"
      @end="handleDragEnd"
    >
      <template #item="{ element }">
        <div class="item-card">
          <div class="item-title">{{ element.name }}</div>
          <div class="item-content">{{ element.description }}</div>
        </div>
      </template>
    </draggable>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import draggable from 'vuedraggable';

// 列表数据
const list = ref([
  { id: 1, name: '项目1', description: '描述1' },
  { id: 2, name: '项目2', description: '描述2' },
  { id: 3, name: '项目3', description: '描述3' }
]);

// 拖拽结束事件
const handleDragEnd = (evt) => {
  const { newIndex, oldIndex } = evt;
  console.log('从位置' + oldIndex + '移动到' + newIndex);
};
</script>

<style scoped>
.item-card {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  padding: 15px;
  margin-bottom: 10px;
  background: #fff;
  cursor: move;
}

.item-title {
  font-weight: bold;
  margin-bottom: 8px;
}

.item-content {
  color: #666;
}
</style>
  1. 重要属性说明
  • v-model : 绑定数据源
  • item-key : 项目的唯一标识
  • group : 分组名称,相同组名的可以互相拖拽
  • @end : 拖拽结束事件
  • @start : 开始拖拽事件
  • @change : 顺序改变事件
  1. 分组拖拽
<template>
  <div class="group-container">
    <div v-for="group in groups" :key="group.id" class="group">
      <h3>{{ group.name }}</h3>
      <draggable 
        v-model="group.items"
        :group="{ name: 'items' }"
        item-key="id"
        @end="(evt) => handleDragEnd(evt, group)"
      >
        <template #item="{ element }">
          <div class="item-card">
            {{ element.name }}
          </div>
        </template>
      </draggable>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import draggable from 'vuedraggable';

const groups = ref([
  {
    id: 1,
    name: '分组1',
    items: [
      { id: 1, name: '项目1' },
      { id: 2, name: '项目2' }
    ]
  },
  {
    id: 2,
    name: '分组2',
    items: [
      { id: 3, name: '项目3' },
      { id: 4, name: '项目4' }
    ]
  }
]);

const handleDragEnd = (evt, group) => {
  const { newIndex, oldIndex } = evt;
  console.log(`在分组 ${group.name} 中从位置 ${oldIndex} 移动到 ${newIndex}`);
};
</script>

<style scoped>
.group-container {
  display: flex;
  gap: 20px;
}

.group {
  flex: 1;
  padding: 15px;
  background: #f5f7fa;
  border-radius: 4px;
}

.item-card {
  background: white;
  padding: 10px;
  margin: 5px 0;
  border-radius: 4px;
  cursor: move;
}
</style>
  1. 注意事项
  • 确保每个拖拽项都有唯一的 key
  • 使用 @end 事件而不是 @change 事件来处理排序结果
  • 如果需要在拖拽时保存滚动位置,可以在 @start 事件中记录位置
  • 组件卸载时注意清理相关事件监听
  1. 日常整理!