为什么随机数做 key 更差 目录1. key 本来是干什么的2. 随机数为什么有问题问题在于3. 为什么说“更差”① 失去 diff 优化能力② 组件状态会丢失③ 生命周期频繁触发④ 容易掩盖真正问题4. 和 index 做 key 比谁更差index 做 key 已经不太好了随机数比 index 更差5. 正确的 key 应该具备什么特征6. 什么叫“稳定”稳定示例不稳定示例7. 为什么有时候随机 key 看起来“有效”8. 有没有少数场景可以故意改 key9. 面试怎么答10. 简短背诵版11. 一句话总结一句话因为key的作用是让 Vue 稳定识别“这是同一个节点”还是“这是新节点”而随机数会让每次渲染的key都变导致 Vue 认为所有节点都是新的。这比不用、乱用key还更糟。1.key本来是干什么的在v-for里Vue 要比较新旧虚拟 DOM判断哪些节点可以复用哪些节点需要移动哪些节点需要删除或新增这时候key就像节点的身份证。比如div v-foritem in list :keyitem.id {{ item.name }} /divitem.id是稳定的Vue 就知道id1还是原来那个节点id2还是原来那个节点于是它就能高效复用。2. 随机数为什么有问题比如你这样写div v-foritem in list :keyMath.random() {{ item.name }} /div或者div v-for(item, index) in list :keyindex - Math.random() {{ item.name }} /div问题在于每次组件重新渲染时Math.random()都会生成新的值。也就是说上一次渲染key 可能是0.123下一次渲染key 变成0.876Vue 一看哦这不是原来那个节点了是一个全新的节点。于是它不会复用旧节点而是销毁旧节点新建新节点这就很浪费。3. 为什么说“更差”① 失去 diff 优化能力Vue 的更新本来是为了尽可能少地改动真实 DOM但随机key会让 Vue 误以为整个列表全变了。结果就是原本只改 1 项现在可能整列都重建性能明显更差。② 组件状态会丢失如果列表项里有子组件RowItem v-foritem in list :keyMath.random() :itemitem /由于每次key都变子组件会不断被重新创建。会导致输入框内容丢失焦点丢失组件内部data重置动画状态丢失mounted反复执行这比单纯“页面刷新一下”问题还大。③ 生命周期频繁触发因为组件反复销毁重建所以会频繁触发beforeUnmount / unmountedbeforeMount / mounted这不仅性能差还可能带来副作用比如重复请求接口重复注册事件重置定时器④ 容易掩盖真正问题有些人用随机key是为了“强制刷新页面”MyComponent :keyMath.random() /表面上问题解决了因为组件被重建了。但本质上只是绕过了响应式问题而不是解决问题。真正该排查的可能是Vue2 新增属性没被监听数组索引赋值不更新解构导致响应式丢失修改的不是响应式对象随机key只是“重装系统”不是“修 bug”。4. 和index做 key 比谁更差index做 key 已经不太好了因为如果列表发生插入删除排序会导致节点错位复用。例如div v-for(item, index) in list :keyindex input v-modelitem.name / /div如果中间插入一条数据后面的 index 全变可能导致输入框状态错位。随机数比index更差因为index至少在本次列表顺序不变时还算稳定随机数是每次渲染都不稳定所以从稳定性上说业务唯一 id index 随机数随机数通常是最差选项。5. 正确的key应该具备什么特征一个好的key应该唯一稳定可预测例如:keyitem.id这是最理想的。如果没有 id也尽量找业务上稳定的字段:keyitem.code :keyitem.uuid :keyitem.name _ item.type6. 什么叫“稳定”稳定的意思是同一条数据在多次渲染中key不应该变化例如 item 没变那它的key也不应该变。稳定示例:keyitem.id不稳定示例:keyDate.now() :keyMath.random() :keyuuid() // 如果每次渲染都重新生成这些都不稳定。7. 为什么有时候随机 key 看起来“有效”因为它相当于强制 Vue 放弃复用直接重建组件所以某些场景会表现为页面更新了旧状态清掉了第三方组件重新初始化了但这属于“强制重建策略”不是正常 diff 更新。8. 有没有少数场景可以故意改 key有但那不是“随机数做 key”而是受控地改变 key。比如你明确想重置一个组件MyForm :keyformVersion /this.formVersion这样是有目的地让组件重建。这个场景是合理的因为key 可控变化时机明确只在需要时变化而不是每次渲染都随机变化。9. 面试怎么答你可以这样说不建议用随机数做key因为key的本质是给虚拟 DOM 提供稳定身份便于 Vue 在 diff 时复用节点。如果使用随机数每次渲染key都会变化Vue 会认为所有节点都是新的导致整批节点无法复用只能销毁再重建。这样会带来两个问题一是性能变差因为 diff 优化失效二是组件状态容易丢失比如输入框内容、焦点、子组件内部状态都会被重置。所以key应该尽量使用稳定且唯一的业务字段比如id而不是随机数。10. 简短背诵版随机数做key更差因为它不稳定。每次渲染key都变化Vue 就无法复用原来的节点只能销毁并重新创建导致性能变差、组件状态丢失。key应该使用稳定且唯一的值比如业务 id。11. 一句话总结key是身份标识不是刷新按钮随机数让身份每次都变所以是最差的key。