Appearance
v-for 指令用来"循环生成多个相同的元素",就像 JavaScript 的 for...of 循环。
遍历数组
最常用的场景是把数组里的每一项渲染出来:
vue
<template>
<ul>
<li v-for="item in items" :key="item.id">
{{ item.name }}
</li>
</ul>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, name: 'Vue' },
{ id: 2, name: 'React' },
{ id: 3, name: 'Angular' }
]
}
}
}
</script>
页面输出:
• Vue
• React
• Angular
📝 Note:v-for 的语法v-for="item in items" 读作:"从 items 数组里逐个取出元素,存到变量 item 里,然后用 item 渲染这一行。"
获取索引
如果你还需要知道"当前是第几个",加一个括号:
vue
<li v-for="(item, index) in items" :key="item.id">
{{ index + 1 }}. {{ item.name }}
</li>
输出:
1. Vue
2. React
3. Angular
💡 Tip:注意index 从 0 开始,显示的时候一般需要 index + 1。
遍历对象
v-for 也能遍历对象的属性:
vue
<template>
<p v-for="(value, key, index) in user" :key="key">
{{ index }}. {{ key }}: {{ value }}
</p>
</template>
<script>
export default {
data() {
return {
user: { name: '张三', age: 18, city: '北京' }
}
}
}
</script>
输出:
0. name: 张三
1. age: 18
2. city: 北京
三个参数的顺序是:值 → 键 → 索引。
遍历数字范围
vue
<span v-for="n in 5" :key="n">{{ n }} </span>
输出:1 2 3 4 5(从 1 开始,到 5)
key 属性 — 很重要!
每个 v-for 的元素都应该加上 :key,这是 Vue 识别每个元素的身份标识。
为什么需要 key?
Vue 更新列表时,需要知道"哪一行是新加的、哪一行是删掉的、哪一行改了"。没有 key,Vue 就只能"按位置对号入座",容易出错。 举个例子:你有一个列表 [A, B, C],你想在最前面插入 D 变成 [D, A, B, C]:
- 没有 key:Vue 把第一行从 A 改成 D,第二行 B 改成 A...四行都要更新
- 有 key:Vue 一看,D 是新的,放最前面;A、B、C 都在,不用动
用什么做 key?
vue
<!-- ✅ 用唯一 ID -->
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
<!-- ❌ 不要用索引(index) -->
<li v-for="(item, index) in items" :key="index">{{ item.name }}</li>
用 index 做 key 的坏处:当你对数组做插入/删除时,元素的 index 会变,Vue 就分不清谁是谁了。 💡 Tip:记住只要有 v-for,就一定要加 :key,且 key 要用唯一的、不变的值。
在 <template> 上使用 v-for
和 v-if 一样,v-for 也可以加在 <template> 上同时渲染多个元素:
vue
<template v-for="item in items" :key="item.id">
<h3>{{ item.name }}</h3>
<p>{{ item.desc }}</p>
</template>
实际例子:待办事项列表
vue
<template>
<div>
<input v-model="newTodo" @keyup.enter="addTodo" placeholder="输入待办事项">
<ul>
<li v-for="todo in todos" :key="todo.id">
{{ todo.text }}
<button @click="removeTodo(todo.id)">删除</button>
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
newTodo: '',
todos: [
{ id: 1, text: '学 Vue' },
{ id: 2, text: '写代码' }
],
nextId: 3
}
},
methods: {
addTodo() {
if (this.newTodo.trim()) {
this.todos.push({ id: this.nextId++, text: this.newTodo })
this.newTodo = '' // 清空输入框
}
},
removeTodo(id) {
this.todos = this.todos.filter(t => t.id !== id)
}
}
}
</script>
新手常见问题
Q:不写 :key 会怎样? A:能运行,但 Vue 会在控制台给你一个警告,而且列表更新时可能出 bug。养成习惯,有 v-for 必有 :key。 Q:为什么我的列表没更新? A:检查你是不是用 this.items[0] = xxx 这样直接赋值。Vue 2 不会检测这种改动,要用 splice 或整体替换数组。Vue 3 没这个问题。 下一步: 💡 Tip:Composition API 写法(Vue 3)
vue
<script setup>
import { ref } from 'vue'
const items = ref([{ id: 1, name: 'Vue' }, { id: 2, name: 'React' }])
</script>
模板部分 (v-for、:key) 完全不变。 详见: