Vue列表渲染的坑:为什么不能用index当key?血泪教训总结!

前言

大家好,我是小杨,一个写了6年前端的老司机。今天要聊一个Vue里看似简单但90%新手都会踩的坑------用index当key。这玩意表面人畜无害,实际暗藏杀机,轻则数据错乱,重则性能爆炸。不信?往下看我的翻车实录!


一、index当key的灾难现场

上周我写了个代办事项列表,代码长这样:

html 复制代码
<!-- 天真无邪的写法 -->
<ul>
  <li v-for="(todo, index) in todos" :key="index">
    {{ 我 }}的任务:{{ todo.text }}
  </li>
</ul>

看起来没问题对吧?直到我加了删除功能...

翻车过程:

  1. 假设有三个任务:["买菜", "写代码", "摸鱼"]

  2. 删除第二个"写代码"后

  3. Vue根据index认为:

    • 旧节点0(买菜)→ 新节点0(买菜) ✔
    • 旧节点1(写代码)→ 新节点1(摸鱼) ❌
    • 旧节点2(摸鱼)→ 被删除

结果:本该显示["买菜", "摸鱼"],却可能触发组件异常复用,导致:

  • 输入框状态错乱
  • 动画效果错位
  • 控制台疯狂警告

二、为什么index是万恶之源?

1. 数组变异操作直接暴击

  • 当发生删除/插入时,所有后续元素的index全变了
  • 但Vue觉得:"咦,key=1的节点还在嘛(其实内容已经物是人非)"

2. 性能杀手

看这个例子:

js 复制代码
// 初始数据
const todos = [
  { id: 1, text: "买菜" },
  { id: 2, text: "写代码" }
]

// 头部插入新任务
todos.unshift({ id: 3, text: "开会" })

用index当key时:

  • 所有
  • 的key都变了(0→1, 1→2)
  • 导致全部DOM重新渲染(其实只需要在头部加一个DOM)

用id当key时:

  • 只有新加的
  • 会创建
  • 其他DOM原地复用

三、正确姿势指南

✅ 方案1:用数据唯一标识

html 复制代码
<li v-for="todo in todos" :key="todo.id">
  {{ todo.text }}
</li>

✅ 方案2:实在没id怎么办?

js 复制代码
// 方法1:前端生成唯一ID
todos.map(todo => ({
  ...todo,
  _id: Math.random().toString(36).slice(2)
}))

// 方法2:用内容哈希(仅限内容不会重复)
:key="hash(todo.text)"

❌ 这些情况千万别用index!

  • 列表有增删操作
  • 列表项包含表单元素
  • 需要过渡动画
  • 列表项是有状态组件

四、血的教训

去年我们项目有个诡异bug:

  1. 表格允许拖拽排序
  2. 每行有个计数器组件
  3. 拖拽后计数器的值会随机交换

排查三天发现 :有人写了:key="index"。改成:key="row.id"后,世界和平了。


五、总结

  • 🚫 index当key ≈ 埋地雷
  • 唯一id当key = 稳如老狗
  • 💡 没有id就创造id(但别用index!)

下次写v-for时,记得摸摸头顶------哦不,记得检查key!你的头发会感谢你。

⭐ 写在最后

请大家不吝赐教,在下方评论或者私信我,十分感谢🙏🙏🙏.

✅ 认为我某个部分的设计过于繁琐,有更加简单或者更高逼格的封装方式

✅ 认为我部分代码过于老旧,可以提供新的API或最新语法

✅ 对于文章中部分内容不理解

✅ 解答我文章中一些疑问

✅ 认为某些交互,功能需要优化,发现BUG

✅ 想要添加新功能,对于整体的设计,外观有更好的建议

✅ 一起探讨技术加qq交流群:906392632

最后感谢各位的耐心观看,既然都到这了,点个 👍赞再走吧!

相关推荐
ps_xiaowang21 分钟前
React Query入门指南:简化React应用中的数据获取
前端·其他·react native·react.js
知识分享小能手33 分钟前
微信小程序入门学习教程,从入门到精通,微信小程序开发进阶(7)
前端·javascript·学习·程序人生·微信小程序·小程序·vue3
叫兽~~1 小时前
vite vue 打包后运行,路由首页加载不出来
vue.js·vue
sophie旭2 小时前
一道面试题,开始性能优化之旅(8)-- 构建工具和性能
前端·面试·性能优化
市民中心的蟋蟀2 小时前
第三章 钩入React 【上】
前端·react.js·架构
Holin_浩霖3 小时前
为什么typeof null 返回 "object" ?
前端
PanZonghui3 小时前
Zustand 实战指南:从基础到高级,构建类型安全的状态管理
前端·react.js
PanZonghui3 小时前
Vite 构建优化实战:从配置到落地的全方位性能提升指南
前端·react.js·vite
_extraordinary_3 小时前
Java Linux --- 基本命令,部署Java web程序到线上访问
java·linux·前端
用户1456775610373 小时前
推荐一个我私藏的电脑神器:小巧、无广、功能强到离谱
前端