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
相关产品推荐
相关产品推荐

