v-for="(item, index) in items" 遍历数组渲染列表;每个循环元素必须给唯一 v-for="(item, index) in items" 遍历数组渲染列表;每个循环元素必须给唯一 v-for="(item, index) in items" 遍历数组渲染列表;每个循环元素必须给唯一
Vue 词条目录
前端Wiki/Vue/进阶/条件与列表渲染

列表渲染 v-for 与 key

v-for="(item, index) in items" 遍历数组渲染列表;每个循环元素必须给唯一 :key。key 的作用是让 Vue 在 diff 时正确匹配新旧节点——更新数据后,列表项是「移动到新位置」而不是「按顺序重新渲染」。

key 必须稳定且唯一(数据 id 最佳),用 index 作 key 是常见反模式:在列表头部插入元素时,index 对应关系全乱,会导致状态错位(输入框内容串行)与性能下降。

  • v-for 支持 (item, index) 与 (value, key, index) 遍历对象
  • :key 绑定唯一 id,让 diff 精确匹配,列表项可复用而非重渲染
  • 禁止用 index 作 key:插入/删除会打乱对应关系,状态串行
HTML
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>列表渲染与 key</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
  <div id="app">
    <ul>
      <!-- 用数据 id 作 key,插入/删除时列表项正确复用 -->
      <li v-for="t in todos" :key="t.id">
        <input type="checkbox" v-model="t.done">
        {{ t.text }}
        <button @click="remove(t.id)">删除</button>
      </li>
    </ul>
    <button @click="add">头部插入</button>
  </div>

<script>
  const { createApp, ref } = Vue;
  createApp({
    setup() {
      const todos = ref([
        { id: 1, text: '学 Vue', done: false },
        { id: 2, text: '写 demo', done: true }
      ]);
      let seq = 3;
      const add = () => todos.value.unshift({ id: seq++, text: '新任务 ' + seq, done: false });
      const remove = (id) => todos.value = todos.value.filter(t => t.id !== id);
      return { todos, add, remove };
    }
  }).mount('#app');
</script>
</body>
</html>
本节要点v-for 必须配唯一稳定的 :key(数据 id);key 决定 diff 能否复用节点,index 是反模式。