You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3使用vuedraggable如何获取拖拽元素的起点与终点列表

解决方案

你不需要监听所有列表变化,搭配start和end两个事件就能实现需求,move事件是拖拽过程中高频触发的,不适合做归属修改逻辑,容易出现异常。

核心修改点:

  • 新增临时变量存储拖拽起点信息
  • 给每个draggable组件增加列表标识属性,用来识别来源/目标列表
  • 修正clone方法补充uuid字段
  • 用end事件在拖拽结束后统一处理归属属性修改

修改后的完整代码:

template部分(仅标注修改的draggable部分,其余不变)
<!-- 列表1 draggable增加data-list-id属性 -->
<draggable
  class="dragArea list-group"
  :list="list1"
  :clone="clone"
  :group="{ name: 'people', pull: pullFunction }"
  @start="start"
  @end="handleDragEnd"
  item-key="id"
  data-list-id="1"
>
<!-- 列表2 draggable增加data-list-id属性,去掉多余的move事件监听 -->
<draggable
  class="dragArea list-group"
  :list="list2"
  :clone="clone"
  @start="start"
  @end="handleDragEnd"
  group="people"
  item-key="id"
  data-list-id="2"
>
script部分
import draggable from "vuedraggable";
let idGlobal = 8;
export default {
  name: "clone-on-control",
  display: "Clone on Control",
  instruction: "Press Ctrl to clone element from list 1",
  order: 4,
  components: {
    draggable
  },
  data() {
    return {
      list1: [
        { name: "Jesus", id: 1, list:1, uuid: "ffcc4608-3b1b-11ec-8d3d-0242ac130003" },
        { name: "Paul", id: 2, list:1, uuid: "0649fe6c-3b1c-11ec-8d3d-0242ac130003" },
        { name: "Peter", id: 3, list:1, uuid: "0e81b8e0-3b1c-11ec-8d3d-0242ac130003" }
      ],
      list2: [
        { name: "Luc", id: 5, list:2, uuid: "15314048-3b1c-11ec-8d3d-0242ac130003" },
        { name: "Thomas", id: 6, list:2, uuid: "1a4df63e-3b1c-11ec-8d3d-0242ac130003" },
        { name: "John", id: 7, list:2, uuid: "20ac6baa-3b1c-11ec-8d3d-0242ac130003" }
      ],
      controlOnStart: true,
      // 新增:存储拖拽起点信息
      dragOrigin: null
    };
  },
  methods: {
    clone({name, id, list, uuid}) {
      console.log('clone', name, id, list, idGlobal++)
      // 克隆时补充uuid:如果需要新uuid就用 crypto.randomUUID() 生成,需要和原元素一致就直接传原uuid
      return {name, id: id, list, uuid: crypto.randomUUID()};
    },
    pullFunction(item) {
      console.log('pullIs', item);
      return this.controlOnStart ? "clone" : true;
    },
    start(event) {
      console.log("start")
      this.controlOnStart = event.originalEvent.ctrlKey;
      // 存储拖拽起点信息:源列表ID、被拖拽的元素原始数据
      this.dragOrigin = {
        fromListId: event.from.dataset.listId,
        element: event.item.__vueParentComponent.props.element
      }
    },
    handleDragEnd(event) {
      // 没有移动到其他列表直接返回
      if (!event.to) return
      const targetListId = event.to.dataset.listId
      // 源和目标列表相同不需要修改
      if (this.dragOrigin.fromListId === targetListId) return
      
      // 获取被添加到目标列表的新元素(克隆模式下是新生成的元素,移动模式下是原元素)
      const targetList = targetListId === '1' ? this.list1 : this.list2
      const movedElement = targetList.find(item => item.id === this.dragOrigin.element.id)
      
      if (movedElement) {
        // 修改归属属性
        movedElement.list = Number(targetListId)
      }
      
      // 清空临时存储
      this.dragOrigin = null
    }
  }
};

扩展多列表适配方案

如果后续要扩展更多列表,只需要给新增的draggable设置对应data-list-id,并且把列表数据统一存在一个数组/对象里,不需要新增额外逻辑,直接通过targetListId匹配对应列表操作即可。

内容的提问来源于stack exchange,提问作者dmitriy_one

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 11:27:03