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

Vue.js使用index作为v-for的key时列表删除异常问题求解

问题原因

这个问题的核心是v-for使用数组下标index作为key导致的虚拟DOM节点复用异常:

  • Vue的虚拟DOM Diff算法依赖key判断列表节点是否可复用,key是节点的唯一身份标识
  • 当你用index作为key时,key会跟随数组元素的位置变化自动更新。比如数组原有4个元素下标为0/1/2/3,删除下标为2的倒数第二项后,原有下标为3的元素下标会变为2
  • 此时Vue检测到列表最终只有3个元素,对应key为0/1/2,会判定最后一个key=3的节点需要移除,而key=2的节点只是内容更新,最终渲染出来就会表现为“最后一项被删除”,实际上数组本身的数据是正确的,只是渲染层出现了复用错误。

修复方案

给每个数组项添加唯一不变的标识作为key,不要使用动态变化的下标:

  1. 修改JavaScript逻辑,给每个item新增唯一id字段:
Vue.createApp({
  data() {
    return {
      parentMessage: 'Parent',
      nextId: 3, // 初始id从3开始,对应原有2条数据的id
      items: [
        { id: 1, message: 'Foo' }, 
        { id: 2, message: 'Bar' }
      ]
    }
  },
  methods: {
    removeItem(index){
      this.items.splice(index, 1); 
    },
    addItem(){
      this.items.push({
        id: this.nextId++, // 每次新增id自增,保证唯一
        message: "hello"
      }); 
    }
  }
}).mount('#array-with-index')
  1. 修改HTML中v-for的key绑定:
<ul id="array-with-index" class="demo">
  <li v-for="(item, index) of items" :key = "item.id">
    {{ parentMessage }} - {{ index }} - {{ item.message }}
    <button @click = "removeItem(index)"> remove </button>
  </li>
  
  <button @click = "addItem"> add </button>
</ul>

修改后每个节点的key跟随元素本身,不会因为数组顺序、长度变化而改变,Diff算法可以准确识别需要删除的节点,不会出现复用错误。

注意:仅当列表完全静态、不会发生增删、排序操作时,才可以使用index作为key,其余场景都建议使用业务唯一标识作为key。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 15:21:03