Vue报Duplicate keys detected: '15249'. This may cause an update error.报错原因及解决方案

401 阅读2分钟

问题描述:

image.png 在vue2.x版本中项目报错Duplicate keys detected: '15249'. This may cause an update error.是因为vue发现循环中的数据的key值不是唯一的而引发的错误。

译为中文意思大概为:检测到重复的密钥:“15249”。这可能会导致更新错误

解决方法常规的就是让数据的key保持唯一性,不可重复。通常我们可以使用数据对象中的id、phone等唯一性字段来作为key值。

问题所在:在同一层DOM节点上,vue发现key不是唯一的,是会报错的,但是如果不是在同一层DOM使用v-for循环,则不会报错。所以呢,如果不在同一层DOM上进行for循环,就可以保证了key的唯一性。 (对于:key的作用还没有接触到。)

当然我也在网上看到一些其他的解决方案,比如类似于

v-for="(item,index) in usersOptions" :key="'info-'+index"

这样的手动拼接的key,但是:key是手动进行修改的,如果忘记:key的数据和本来的数据是不一样的.在后期维护起来不是那么方便。

如果数据中没有类似于id这样的唯一性字段,我们也可以使用index来作为key值,但是也并非所有情况都适用于:key="index"。

使用index作为key可能会产生严重的效率问题!

用index作为key可能会引发的问题:

    1. 若对数据进行:逆序添加、逆序删除等破坏顺序操作:会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。

    2. 如果结构中还包含输入类的DOM:会产生错误DOM更新 ==> 界面有问题。

    3. 注意!如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。

示例代码:

<el-select
  v-if="loginOptions.type"
  v-model="loginOptions.user"
  style="width:100%;"
  value-key="username"
  popper-class="selectDropdown"
  size="small"
  filterable
  :filter-method="handleCityFilter"
  clearable
  placeholder="可输入用户名或姓名搜索后选择"
  @change="usernameChange"
>
  <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
  <el-option v-for="item in usersOptions" :key="item.id" :label="item.name == item.username ? item.name : item.username + '(' + item.name + ')'" :value="item" />
</el-select>