Vue3循环语句

Vue 3 循环语句完全指南

本文档从零开始讲解 Vue 3 里的循环语句:如何根据数组或对象重复渲染多份内容,即 v-for 的方方面面,包括语法、:key、与 v-if 的配合、常见场景和易错点,配有大量示例,适合新手系统学习。


一、为什么需要“循环”?

页面上经常要根据一份数据列表生成多块相似的 HTML,例如:

  • 根据商品列表渲染多个商品卡片
  • 根据菜单项渲染导航链接
  • 根据评论列表渲染多条评论

若数据有 10 条,你不想手写 10 遍相同的标签。在 Vue 里,只要写一遍结构,用 v-for 声明“按哪份数据循环”,Vue 就会自动根据数据的每一项渲染出一份 DOM。
这种“按数据重复渲染”的写法,就是本文要讲的循环语句


二、v-for 是什么?

v-for 是 Vue 的列表渲染指令:写在要重复的那个元素(或 <template>)上,指定“遍历谁、当前项叫什么、要不要索引”等,Vue 会循环生成多份 DOM。

基本形式:

v-for="(项, 索引?) in 数据源"
  • 数据源:通常是数组或对象(也可以是数字范围,见后文)。
  • :当前这一轮循环拿到的“当前项”(数组元素、对象属性值等)。
  • 索引:可选,表示当前是第几项(从 0 开始)。

下面按“遍历数组 → 遍历对象 → 遍历数字 → key → 其他用法”顺序讲。


三、遍历数组

数组是最常用的数据源:每一项对应一个元素,可以拿到当前项索引

3.1 基本语法

语法: v-for="(item, index) in list"

  • item:当前这一项(你可以随便起名,如 itemuserproduct)。
  • index:当前项的索引,从 0 开始(可选,不需要可以不写)。
  • list:你在 script 里定义的数组(ref 或 reactive 的数组)。
<template>
  <ul>
    <li v-for="(item, index) in fruits" :key="item.id">
      {{ index + 1 }}. {{ item.name }}
    </li>
  </ul>
</template>

<script setup>
import { ref } from 'vue'
const fruits = ref([
  { id: 1, name: '苹果' },
  { id: 2, name: '香蕉' },
  { id: 3, name: '橙子' }
])
</script>

渲染结果示例:

    1. 苹果
    1. 香蕉
    1. 橙子

注意: 这里用了 :key="item.id"。使用 v-for 时强烈建议始终绑定 :key,且 key 要唯一、稳定(见第五节)。

3.2 只写“项”,不写“索引”

若用不到索引,可以只写一个变量:

<template>
  <ul>
    <li v-for="name in names" :key="name">{{ name }}</li>
  </ul>
</template>

<script setup>
import { ref } from 'vue'
const names = ref(['小明', '小红', '小刚'])
</script>

当数组项是简单值(字符串、数字)且没有 id 时,可以用该项本身当 key(前提是项不重复)。若有重复或是对象,仍建议用唯一 id 当 key。

3.3 解构当前项(适合对象数组)

若每一项是对象,可以在 v-for 里直接解构,模板里写起来更短:

<template>
  <ul>
    <li v-for="({ id, name, price }, index) in products" :key="id">
      {{ index + 1 }}. {{ name }} - ¥{{ price }}
    </li>
  </ul>
</template>

<script setup>
import { ref } from 'vue'
const products = ref([
  { id: 1, name: '苹果', price: 5 },
  { id: 2, name: '香蕉', price: 3 }
])
</script>

四、遍历对象

除了数组,还可以遍历对象:遍历的是对象的可枚举属性,可以拿到属性值、属性名,以及可选的索引

4.1 基本语法

语法: v-for="(value, key, index) in object"

  • value:当前属性的值。
  • key:当前属性的名(字符串)。
  • index:第几个属性(从 0 开始,可选)。
<template>
  <ul>
    <li v-for="(value, key) in user" :key="key">
      {{ key }}: {{ value }}
    </li>
  </ul>
</template>

<script setup>
import { ref } from 'vue'
const user = ref({
  name: '小明',
  age: 18,
  city: '北京'
})
</script>

渲染结果示例:

  • name: 小明
  • age: 18
  • city: 北京

对象遍历时,遍历顺序会按“对象属性的创建顺序”,在多数场景下可认为顺序是稳定的,但若对顺序有强要求,更推荐用数组存“键值对”再遍历数组。

4.2 带索引的对象遍历

<template>
  <ul>
    <li v-for="(value, key, index) in info" :key="key">
      第 {{ index + 1 }} 个属性:{{ key }} = {{ value }}
    </li>
  </ul>
</template>

<script setup>
import { ref } from 'vue'
const info = ref({
  a: 1,
  b: 2,
  c: 3
})
</script>

五、遍历数字范围(从 1 到 N)

语法: v-for="n in 数字"
这里会从 1 循环到该数字(包含),n 依次为 1、2、3、…、数字。注意是 1 开始,不是 0。

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

渲染结果: 1 2 3 4 5(中间是空格,因为 span 是行内元素)。

适合做“星级显示、简单序号”等,不需要先准备数组。


六、为什么必须写 :key?写什么?

6.1 key 的作用

Vue 在更新“列表”时,需要知道哪一项对应哪一块 DOM,才能正确做复用、移动、增删,避免错乱或重复。
:key 就是给“每一项”一个唯一标识
key 相同 → Vue 认为是同一条数据 → 会复用对应 DOM;key 变了或新增 → Vue 会新建或移除 DOM。

不写 key 时,Vue 会退化为用“索引”来猜,在有增删、排序的列表里容易出 bug(例如勾选错行、输入错行)。所以只要用 v-for,就应尽量写上 :key

6.2 key 写什么?唯一且稳定

  • 有唯一 id 的列表:用 item.id(或其它唯一字段)当 key。
  • 简单值列表且无重复:可以用 该项本身(如 :key="name"),若可能重复则不适合。
  • 不推荐用 index 当 key:在“增删、排序、过滤”时,index 会变,导致 Vue 误判“同一条数据”,出现状态错位(例如输入框、勾选状态跑到别的行)。
<!-- 推荐:用唯一 id -->
<li v-for="item in list" :key="item.id">...</li>

<!-- 简单值且不重复时可用项本身 -->
<li v-for="name in names" :key="name">...</li>

<!-- 不推荐:用 index,列表会增删时易出错 -->
<li v-for="(item, index) in list" :key="index">...</li>

6.3 用 index 当 key 会出什么问题?(示例)

假设列表可删除,且每行有一个输入框。用 index 当 key 时,删掉第一项后,原来的“第二项”会变成“第一项”,但 Vue 复用的是“原来第一项”的 DOM,输入框里的字就会错位。
用唯一 id 当 key,删掉一项后,每一项的 key 仍和正确的数据对应,就不会错位。
因此:能不用 index 就不用,优先用业务上的唯一 id


七、用