安装依赖库

Vue 中实现拖拽排序功能通常使用 vuedraggable 库,它是基于 Sortable.js 的 Vue 封装版本。通过以下命令安装:

npm install vuedraggable

引入组件

在 Vue 组件中导入 vuedraggable

import draggable from 'vuedraggable';

在组件的 components 选项中注册:

export default {
  components: {
    draggable,
  },
  // 其他选项...
};

设置数据模型

确保待办任务列表是一个响应式数组,例如:

data() {
  return {
    tasks: [
      { id: 1, text: '任务一' },
      { id: 2, text: '任务二' },
      { id: 3, text: '任务三' },
    ],
  };
},

实现拖拽列表

在模板中使用 draggable 组件包裹任务列表,并绑定数据:

<draggable v-model="tasks" item-key="id">
  <template #item="{ element }">
    <div class="task-item">
      {{ element.text }}
    </div>
  </template>
</draggable>

添加样式

为拖拽项添加基本样式以提升交互体验:

.task-item {
  padding: 10px;
  margin: 5px 0;
  background: #f8f9fa;
  border: 1px solid #ddd;
  cursor: move;
}

处理拖拽事件

如需监听拖拽事件(如排序完成),可通过 draggable 的事件绑定:

<draggable 
  v-model="tasks" 
  item-key="id"
  @end="onDragEnd"
>
  <!-- 模板内容 -->
</draggable>

在方法中定义事件处理逻辑:

methods: {
  onDragEnd() {
    console.log('任务顺序已更新', this.tasks);
    // 可在此处添加保存顺序的逻辑(如调用API)
  },
},

优化性能

对于大型列表,可通过 ghost-classchosen-class 优化拖拽视觉反馈:

<draggable
  v-model="tasks"
  item-key="id"
  ghost-class="ghost"
  chosen-class="chosen"
>
  <!-- 模板内容 -->
</draggable>

.ghost {
  opacity: 0.5;
  background: #c8ebfb;
}
.chosen {
  background: #f0f0f0;
}

兼容性注意事项

如需支持移动端,确保 draggabletouchStartThreshold 属性适配触摸操作:

<draggable
  v-model="tasks"
  :touchStartThreshold="10"
>
  <!-- 模板内容 -->
</draggable>

完整组件示例

整合后的单文件组件示例:

<template>
  <draggable
    v-model="tasks"
    item-key="id"
    @end="onDragEnd"
    ghost-class="ghost"
    chosen-class="chosen"
  >
    <template #item="{ element }">
      <div class="task-item">
        {{ element.text }}
      </div>
    </template>
  </draggable>
</template>

<script>
import draggable from 'vuedraggable';
export default {
  components: { draggable },
  data() {
    return {
      tasks: [
        { id: 1, text: '任务一' },
        { id: 2, text: '任务二' },
        { id: 3, text: '任务三' },
      ],
    };
  },
  methods: {
    onDragEnd() {
      // 保存逻辑...
    },
  },
};
</script>

<style scoped>
.task-item {
  padding: 10px;
  margin: 5px 0;
  background: #f8f9fa;
  border: 1px solid #ddd;
  cursor: move;
}
.ghost {
  opacity: 0.5;
  background: #c8ebfb;
}
.chosen {
  background: #f0f0f0;
}
</style>

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐