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

Vue.js拖拽功能中如何解决数组内重复ID问题

问题解决:Vue拖拽组件中出现重复Key的错误

问题根源分析

你的onDrop函数存在两个核心逻辑错误,导致拖回原位置时出现重复ID:

  1. 未正确移除原位置的元素:你在filter中始终返回child,相当于没有过滤掉任何元素,原分类里的目标项依然存在。
  2. 不必要的全量遍历+重复添加:使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 10:01:16