v-for与key的作用
v-for 是 Vue 的列表渲染指令,配合 key 属性可以优化渲染性能和保证组件状态正确。
v-for 基本用法
JavaScript
// 遍历数组
<div v-for="item in items" :key="item.id">
{{ item.name }}
</div>
// 遍历对象
<div v-for="(value, key) in user" :key="key">
{{ key }}: {{ value }}
</div>
// 指定索引
<div v-for="(item, index) in items" :key="index">
{{ index + 1 }}. {{ item.name }}
</div>
key 的核心作用
1. 节点身份标识
JavaScript
// 没有 key 的问题
// 原始: [A, B, C]
// 更新后: [X, A, B, C]
// Vue 会就地复用节点,导致:
// A的组件状态(如input值)可能被B复用
2. Diff 算法优化
JavaScript
// patch 函数中使用 key 查找
function findIdxInOld(node, oldCh, start, end) {
for (let i = start; i < end; i++) {
if (sameKey(oldCh[i], node)) return i
}
return -1
}
key 的正确使用
使用唯一 ID(推荐)
JavaScript
// 最佳实践
<div v-for="user in users" :key="user.id">
<input v-model="user.name" />
</div>
使用 index 的风险
JavaScript
// 不推荐:index 作为 key
<div v-for="(item, index) in list" :key="index">
<input :value="item.text" />
</div>
当列表发生插入、删除、排序时,index 会变化,导致组件状态错乱:
JavaScript
// 原始: [{text: 'A'}, {text: 'B'}]
// 输入框A输入"hello"后,在头部插入 {text: 'X'}
// 结果: B的输入框显示"hello"(状态被错误复用)
适用 index 的场景
仅当列表不会变化(纯展示)时才使用 index:
JavaScript
// 纯展示列表,不会增删排序
<div v-for="(item, index) in staticList" :key="index">
{{ item.name }}
</div>
v-for 与 v-if 的优先级
JavaScript
// Vue 2: v-for 优先级高于 v-if
// Vue 3: v-if 优先级高于 v-for
// 不推荐同时使用
<div v-for="item in items" v-if="item.active">
// 推荐:使用 computed 过滤
const activeItems = computed(() => items.filter(i => i.active))
列表动画与 key
JavaScript
<transition-group name="list">
<div v-for="item in items" :key="item.id" class="list-item">
{{ item.name }}
</div>
</transition-group>
transition-group 依赖 key 追踪哪些元素被添加、移除或移动。
要点总结
key是 VNode 的唯一标识,帮助 Diff 算法正确识别节点- 始终使用数据的唯一 ID 作为 key
- 避免在可变列表中使用 index 作为 key
v-for和v-if不应同时使用,用 computed 替代- 动画组件依赖 key 实现正确的过渡效果
📝 发现内容有误?点击此处直接编辑