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

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

相关推荐
掘金安东尼3 分钟前
为什么浏览器要限制 JavaScript 定时器?
前端·javascript·github
学前端搞口饭吃7 分钟前
react context如何使用
前端·javascript·react.js
GDAL12 分钟前
为什么Cesium不使用vue或者react,而是 保留 Knockout
前端·vue.js·react.js
IT_陈寒13 分钟前
《Java 21新特性实战:5个必学的性能优化技巧让你的应用快30%》
前端·人工智能·后端
小谭鸡米花23 分钟前
uni小程序中使用Echarts图表
前端·小程序·echarts
芜青27 分钟前
【Vue2手录11】Vue脚手架(@vue_cli)详解(环境搭建+项目开发示例)
前端·javascript·vue.js
a别念m31 分钟前
前端架构-CSR、SSR 和 SSG
前端·架构·前端框架
麦麦大数据1 小时前
J002 Vue+SpringBoot电影推荐可视化系统|双协同过滤推荐算法评论情感分析spark数据分析|配套文档1.34万字
vue.js·spring boot·数据分析·spark·可视化·推荐算法
BillKu6 小时前
Vue3 + Element-Plus 抽屉关闭按钮居中
前端·javascript·vue.js
DevilSeagull6 小时前
JavaScript WebAPI 指南
java·开发语言·javascript·html·ecmascript·html5