人人都会AI编程

3.3 列表渲染:v-for 遍历、key 属性规范

更新时间:2026-07-09

在 Vue 中,v-for 指令用于基于一个数组或对象渲染一个元素列表,它是页面动态生成重复结构最直接的手段。

v-for 基础用法

v-for 的语法为 item in list,其中 list 是要遍历的数据源,item 是当前元素的别名。在模板中,你可以直接使用 item 来访问每一项的数据。

遍历数组

<template>
  <ul>
    <li v-for="user in users" :key="user.id">
      {{ user.name }} - {{ user.email }}
    </li>
  </ul>
</template>

<script setup>
import { ref } from 'vue'
const users = ref([
  { id: 1, name: 'Alice', email: 'alice@example.com' },
  { id: 2, name: 'Bob', email: 'bob@example.com' }
])
</script>

遍历数组时获取索引
如果需要索引,可以使用 (item, index) in list

<li v-for="(user, index) in users" :key="user.id">
  {{ index + 1 }}. {{ user.name }}
</li>

遍历对象
v-for 也可以遍历对象的属性,语法为 (value, key, index) in object

<li v-for="(value, key, index) in info" :key="key">
  {{ index }} - {{ key }}: {{ value }}
</li>

其中 info 是一个 JavaScript 对象,value 是属性值,key 是属性名,index 是遍历顺序。

遍历数字
当需要一个固定重复次数的列表时,可以传入一个整数:

<span v-for="n in 5" :key="n">{{ n }}</span>

这会渲染 1 到 5 共 5 个 <span>


key 属性规范

使用 v-for 时,必须为每个被遍历的元素提供一个唯一的 key 属性(除非列表永远不会被排序、过滤或重新排列)。key 是 Vue 识别每一个虚拟 DOM 节点的身份标识,直接影响列表更新的效率和正确性。

key 存在的根本原因
当 Vue 更新使用 v-for 渲染的列表时,它默认采用“就地复用”的策略:如果列表的数据顺序发生了变化,Vue 不会移动整个 DOM 元素,而是尝试就地修改每个元素的数据。这种做法在大多数简单场景下能工作,但一旦列表项拥有自身状态(比如输入框里的文本、组件的内部状态),或者列表被频繁增删改排序,就会产生不可预料的渲染错误。

为每个列表项指定唯一的 key 后,Vue 可以精准地追踪每个节点的身份,从而在列表变化时正确地移动、复用、销毁 DOM 节点,保证状态与数据始终对应。

key 的绑定规则

  1. 使用列表中唯一且稳定的标识

优先使用后端返回的数据 ID 作为 key

   <li v-for="item in products" :key="item.id">{{ item.title }}</li>
   
  1. 切勿使用索引(index)作为 key

一个常见的反模式是 :key="index"。当列表的顺序发生变化(比如插入、删除、排序)时,同一索引对应的数据项其实已经变了,但 Vue 认为它们还是同一个节点,从而错误地复用旧的状态。这会导致界面异常或动画错乱。只有在列表一旦生成就永远不会改变顺序的极端场景下,使用 index 才勉强可用,但出于安全考虑,任何动态列表都应避免 index 作为 key。

  1. key 的值必须是字符串或数字

key 直接用数据中的某个值,不要用对象或数组等引用类型。

  1. 不要依赖遍历时的临时变量

比如 v-for="item in items"item 本身如果是对象,不要直接使用 :key="item",因为对象引用会变化,推荐使用其具有唯一性的属性。

正确示例

<!-- 正确:使用稳定的数据 id -->
<li v-for="comment in comments" :key="comment.id">
  {{ comment.text }}
</li>

常见错误示范

<!-- 错误:使用索引,列表重排后状态丢失 -->
<li v-for="(item, index) in list" :key="index">{{ item.name }}</li>

<!-- 错误:没有提供 key(Vue 会报警告) -->
<li v-for="item in list">{{ item.name }}</li>

key 属性对性能的实际意义

在渲染列表时,Vue 会对比新旧虚拟 DOM 树,并尝试最小化真实 DOM 操作。有了 key,Vue 可以精准判断哪些节点可以原地复用,哪些需要移动,哪些必须销毁重建。没有 key 时,Vue 只能盲目地针对每个位置去更新,即便内容完全没变也可能触发不必要的 DOM 操作。对于包含富文本、嵌入组件或动画的长列表,忽略 key 会显著增加渲染成本,并导致状态错乱的诡异 bug。

一句话总结v-for 让你用直观的模板语法把数据变成动态骨架,而 key 确保这个骨架在数据流动时始终保持骨骼正确、肌肉不乱跳。为每个 v-for 提供唯一 key,是 Vue 开发者必须遵守的第一条“铁律”。