#### v-for
1. 渲染列表
```vue
<template>
<ul v-for="(item,index) in list" >
<li>{{ item }}</li>
</ul>
</template>
<script setup>
import { ref } from 'vue';
let list = ref(['苹果', '香蕉', '橙子'])
</script>
```
2. 渲染对象列表
- 
```vue
<ul v-for="(item,index) in list" >
<li>{{ item.name }} - {{ item.age }}</li>
</ul>
```
3. 动态添加列表项
- 
```vue
<template>
<input type="text" v-model="txt" placeholder="请输入内容">
<input type="button" value="添加到列表" @click="btn">
<ul v-for="item in list" >
<li>{{ item}}</li>
</ul>
</template>
<script setup>
import { ref } from 'vue';
let txt = ref('')
let list = ref([])
const btn = ()=>{
list.value.push(txt.value)
}
</script>
```
4. 渲染嵌套列表
- 
```vue
<template>
<ul v-for="(item,index) in list" >
<li>子数组{{index+1}}:
<ul>
<li>{{ item }}</li>
</ul>
</li>
</ul>
</template>
<script setup>
let list = ref([['苹果', '香蕉'], ['橙子', '葡萄']])
</script>
```
5. 分组渲染列表
- 
```vue
<template>
<ul v-for="(item,index) in list">
<h2 v-if="index === 0 || item.group !== list[index-1].group">{{ item.group }}</h2>
<li>{{ item.name }}</li>
</ul>
</template>
<script setup>
list.value.sort((a,b)=>a.group.localeCompare(b.group))
</script>
```
6. 分组渲染列表
- 
- 
```vue
<template>
<input type="button" value="按名字排序" @click="btnName">
<input type="button" value="按年龄排序" @click="btnAge">
<ul v-for="(item,index) in list">
<li>{{ item.name }} - {{ item.age }}</li>
</ul>
</template>
<script setup>
import { ref } from 'vue';
let list = ref([ { name: '张三', age: 20 }, { name: '李四', age: 22 }, { name: '王五', age: 18 } ])
let btnName = ()=>{
list.value.sort((a,b)=>a.name.localeCompare(b.name))
}
let btnAge = ()=>{
list.value.sort((a, b) => a.age - b.age);
}
</script>
```
### 笔记
#### 条件渲染
1. `v-if`
- 也可在 `<template>` 上使用
```html
<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no 😢</h1>
```
- **`v-else-if` 指令**
```html
<div v-if="type === 'A'">A</div>
<div v-else-if="type === 'B'">B</div>
<div v-else-if="type === 'C'">C</div>
<div v-else>Not A/B/C</div>
```
2. `v-show`
- 通过切换 `display` CSS 属性来显示或隐藏元素【元素始终会被渲染,只是样式被切换】
```html
<h1 v-show="ok">Hello!</h1>
```
3. 区别
- `v-if` 初始渲染时条件为假则不渲染任何内容。
- `v-show` 始终渲染元素,仅切换 `display` 属性。
- `v-if` 【切换】开销高,适合条件很少改变;`v-show` 初始渲染开销高但切换开销低,适合频繁切换
#### 列表渲染
- **`v-for` 指令**
- 基于数组或对象渲染列表。
- 需要使用 `item in items` 形式的语法,其中 `items` 是数组或对象,`item` 是迭代项的别名。
- 支持可选的第二个参数表示当前项的位置索引。
```html
<li v-for="(item, index) in items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
```
- **`v-for` 与对象**
- 支持三个参数:`value`、`key` 和 `index`。
```html
<li v-for="(value, key, index) in myObject">
{{ index }}. {{ key }}: {{ value }}
</li>
```
- **`v-for` 与范围值**
- `v-for` 可以直接接受整数值,用于重复渲染指定次数。
```html
<span v-for="n in 10">{{ n }}</span>
```
- **`v-for` 与 `v-if`**
- 建议将 `v-for` 放在 `<template>` 上,再在其内部使用 `v-if`。
```html
<template v-for="todo in todos">
<li v-if="!todo.isComplete">
{{ todo.name }}
</li>
</template>
```
- **通过 `key` 管理状态**:帮助 Vue 跟踪节点的标识,以重用和重新排序现有元素。
```html
<div v-for="item in items" :key="item.id">
<!-- 内容 -->
</div>
```
- `:style` :动态样式绑定
```html
<div :style="{ color: textColor, fontSize: fontSize + 'px' }">Styled Div</div>
```
- **`class` 绑定**
- 使用 `:class="$attrs"` 将父组件传递的属性绑定到子组件的 `class` 上。
```html
<div :class="$attrs">Class Binding</div>
```
- **`v-if` 与 `v-show` 的 DOM 行为**
- `v-if` 无论 `true` 或 `false`,DOM 元素都存在,只是根据条件渲染或销毁。
- `v-show` 使用样式控制显示与否,DOM 元素始终存在。