159 lines
3.6 KiB
Markdown
159 lines
3.6 KiB
Markdown
|
# Vue2 列表渲染(v-for)详解文档
|
|||
|
|
|||
|
## 一、基本概念
|
|||
|
|
|||
|
Vue2 中的 `v-for` 指令用于基于源数据多次渲染元素或模板块。它可以遍历数组、对象和字符串,是构建动态列表的核心指令。
|
|||
|
|
|||
|
## 二、代码示例解析
|
|||
|
|
|||
|
```html
|
|||
|
<div id="app">
|
|||
|
<!-- 遍历数组 -->
|
|||
|
<ul>
|
|||
|
<li v-for="(item, index) in list" :key="item.id">
|
|||
|
{{item}}--{{item.name}}--{{index}}
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<!-- 遍历对象 -->
|
|||
|
<ul>
|
|||
|
<li v-for="(value, key, index) of person" :key="key">
|
|||
|
{{value}}--{{key}}--{{index}}
|
|||
|
</li>
|
|||
|
</ul>
|
|||
|
</div>
|
|||
|
|
|||
|
<script>
|
|||
|
const vm = new Vue({
|
|||
|
el: "#app",
|
|||
|
data: {
|
|||
|
list: [
|
|||
|
{ id: 1, name: "1" },
|
|||
|
{ id: 2, name: "2" },
|
|||
|
{ id: 3, name: "3" },
|
|||
|
{ id: 4, name: "4" }
|
|||
|
],
|
|||
|
person: {
|
|||
|
name: "Bunny",
|
|||
|
age: 16
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
</script>
|
|||
|
```
|
|||
|
|
|||
|
## 三、核心语法
|
|||
|
|
|||
|
### 1. 遍历数组
|
|||
|
```html
|
|||
|
<element v-for="(item, index) in array" :key="uniqueId">
|
|||
|
{{ index }}: {{ item }}
|
|||
|
</element>
|
|||
|
```
|
|||
|
|
|||
|
### 2. 遍历对象
|
|||
|
```html
|
|||
|
<element v-for="(value, key, index) in object" :key="key">
|
|||
|
{{ index }}. {{ key }}: {{ value }}
|
|||
|
</element>
|
|||
|
```
|
|||
|
|
|||
|
### 3. 遍历字符串
|
|||
|
```html
|
|||
|
<element v-for="(char, index) in string" :key="index">
|
|||
|
{{ index }}: {{ char }}
|
|||
|
</element>
|
|||
|
```
|
|||
|
|
|||
|
## 四、关键特性
|
|||
|
|
|||
|
| 特性 | 说明 | 示例 |
|
|||
|
| --------- | ---------------- | ----------------------- |
|
|||
|
| `in`/`of` | 两种语法等效 | `v-for="item in items"` |
|
|||
|
| 索引参数 | 可选的第二个参数 | `(item, index)` |
|
|||
|
| `:key` | 必须的唯一标识 | `:key="item.id"` |
|
|||
|
| 嵌套循环 | 支持多层嵌套 | 嵌套使用 `v-for` |
|
|||
|
|
|||
|
## 五、最佳实践
|
|||
|
|
|||
|
### 1. 正确的 key 使用
|
|||
|
- **必须**为每个节点提供唯一的 `key` 属性
|
|||
|
- **避免**使用索引作为 key(当列表会变化时)
|
|||
|
- **理想** key 应该是数据中的唯一 ID
|
|||
|
|
|||
|
```html
|
|||
|
<!-- 推荐 -->
|
|||
|
<li v-for="item in items" :key="item.id">
|
|||
|
|
|||
|
<!-- 不推荐 -->
|
|||
|
<li v-for="(item, index) in items" :key="index">
|
|||
|
```
|
|||
|
|
|||
|
### 2. 性能优化
|
|||
|
- 对大列表使用虚拟滚动(如 vue-virtual-scroller)
|
|||
|
- 避免在 `v-for` 中使用复杂表达式
|
|||
|
- 必要时使用 `v-if` 和 `v-for` 分离(Vue2 中 `v-for` 优先级更高)
|
|||
|
|
|||
|
### 3. 数组更新检测
|
|||
|
Vue 能检测以下数组方法的变化:
|
|||
|
- `push()`
|
|||
|
- `pop()`
|
|||
|
- `shift()`
|
|||
|
- `unshift()`
|
|||
|
- `splice()`
|
|||
|
- `sort()`
|
|||
|
- `reverse()`
|
|||
|
|
|||
|
## 六、高级用法
|
|||
|
|
|||
|
### 1. 范围迭代
|
|||
|
```html
|
|||
|
<span v-for="n in 10">{{ n }} </span>
|
|||
|
```
|
|||
|
|
|||
|
### 2. 组件中使用
|
|||
|
```html
|
|||
|
<my-component
|
|||
|
v-for="(item, index) in items"
|
|||
|
:item="item"
|
|||
|
:index="index"
|
|||
|
:key="item.id">
|
|||
|
</my-component>
|
|||
|
```
|
|||
|
|
|||
|
### 3. 过滤/排序列表
|
|||
|
```javascript
|
|||
|
computed: {
|
|||
|
filteredItems() {
|
|||
|
return this.items.filter(item => item.isActive);
|
|||
|
},
|
|||
|
sortedItems() {
|
|||
|
return [...this.items].sort((a, b) => a.price - b.price);
|
|||
|
}
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
## 七、常见问题
|
|||
|
|
|||
|
1. **为什么列表不更新?**
|
|||
|
- 确保使用了变异方法修改数组
|
|||
|
- 对于非变异方法,使用新数组替换旧数组
|
|||
|
- 对象属性添加需要使用 `Vue.set`
|
|||
|
|
|||
|
2. **`v-if` 和 `v-for` 一起使用?**
|
|||
|
- Vue2 中不推荐同一元素使用两者
|
|||
|
- 解决方案:
|
|||
|
```html
|
|||
|
<template v-for="item in items">
|
|||
|
<div v-if="item.isVisible" :key="item.id">
|
|||
|
{{ item.name }}
|
|||
|
</div>
|
|||
|
</template>
|
|||
|
```
|
|||
|
|
|||
|
3. **如何获取当前元素?**
|
|||
|
- 通过事件传递:
|
|||
|
```html
|
|||
|
<div v-for="item in items" @click="handleClick(item)">
|
|||
|
```
|