Vue.js拖拽功能中如何解决数组内重复ID问题
问题解决:Vue拖拽组件中出现重复Key的错误
问题根源分析
你的onDrop函数存在两个核心逻辑错误,导致拖回原位置时出现重复ID:
- 未正确移除原位置的元素:你在
filter中始终返回child,相当于没有过滤掉任何元素,原分类里的目标项依然存在。 - 不必要的全量遍历+重复添加:使用
map遍历所有分类,每个分类的children都执行一次逻辑,拖回原分类时会把已经存在的元素再次push进去,造成ID重复。
修复后的代码
onDrop(e, categoryId) { const itemId = parseInt(e.dataTransfer.getData('itemId')) // 1. 定位被拖拽的元素及其原所属分类 let draggedItem = null let originalCategory = null this.categories.forEach(category => { const foundItem = category.children.find(child => child.id === itemId) if (foundItem) { draggedItem = foundItem originalCategory = category } }) if (!draggedItem) return // 未找到元素则终止执行 // 2. 从原分类中移除该元素(使用filter返回新数组确保Vue响应式更新) originalCategory.children = originalCategory.children.filter(child => child.id !== itemId) // 3. 更新元素分类ID并添加到目标分类 draggedItem.categoryId = categoryId this.categories[categoryId].children.push(draggedItem) }
关键修复点说明
- 精准定位原元素:通过
forEach+find快速找到目标元素和它的原分类,避免全量遍历带来的冗余操作。 - 彻底移除原元素:使用
filter返回不包含目标元素的新数组,确保原分类中不再存在该元素,同时保证Vue能检测到数组变化。 - 避免重复添加:只有在移除原元素后,才将其添加到目标分类,无论拖拽到新位置还是原位置,都不会出现ID重复。
额外注意事项
- 确保渲染
children时使用v-for="child in category.children" :key="child.id",Vue依赖唯一的key来跟踪元素身份。 - 如果你的
categories是从后端获取的深层对象,使用filter返回新数组的方式已经能触发Vue的响应式更新,无需额外操作。
内容的提问来源于stack exchange,提问作者Synchro
相关产品推荐
相关产品推荐

