Vue3学习笔记:Day5 条件渲染和列表渲染

使用条件渲染和列表渲染来控制渲染逻辑和内容

渲染

条件渲染

使用v-if v-else-if v-else来控制渲染的组件

1
2
3
4
5
6
7
8
9
10
11
12
<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>

使用v-show来选择展示元素,使用方法和v-if一样

v-showv-if的区别是前者只是单纯的hidden隐藏组件,但后者是将其删除不保留在DOM中,是真正的条件渲染

v-if在渲染条件为假的时候什么也不做,直到条件为真才开始渲染组件,使用时要避免频繁的切换

列表渲染

使用指令v-foritem in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名

当items为一个常数,如n in 10,会将代码块重复渲染十次,而n会依次等于1 2 3 ··· 10

渲染数组

渲染数组有两个参数index,使用方法如(item, index) in items,第一个为数组值,第二个为数组索引,参数是按照顺序来确定是第几个

1
2
3
4
5
<ul id="array-with-index">
<li v-for="(item, index) in items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
</ul>

渲染对象

渲染对象有三个参数,(value, name, index) in myObject第一个为值,第二个为键,第三个为索引

1
2
3
<li v-for="(value, name, index) in myObject">
{{ index }}. {{ name }}: {{ value }}
</li>

Key

使用Key来在列表元素变更时正确的渲染列表,key的值必须是唯一的,详情见文章

1
2
3
<div v-for="item in items" :key="item.id">
<!-- 内容 -->
</div>

更新数组

Vue通过监听数组以下方法来对数组进行响应式更新,通过下列方法更新数组可以直接在列表渲染中更新

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

当使用其他方法来更新数组时,可以直接将原数组替换

1
example1.items = example1.items.filter(item => item.message.match(/Foo/))

替换后不会删除之前的DOM重新渲染整个列表,而是通过算法实现了DOM元素最大范围的复用,所以使用相同元素较多的数组去替换原数组的效率也是不错的

有条件的列表渲染

使用computed计算属性

1
2
3
4
5
6
7
8
9
10
data() {
return {
numbers: [ 1, 2, 3, 4, 5 ]
}
},
computed: {
evenNumbers() {
return this.numbers.filter(number => number % 2 === 0)
}
}
1
<li v-for="n in evenNumbers" :key="n">{{ n }}</li>

可以使用计算方法返回一个符合条件的列表进行遍历

使用v-if

注意:v-ifv-for不可以同时作用在一个标签内

当它们处于同一节点,v-if 的优先级比 v-for 更高,这意味着 v-if 将没有权限访问 v-for 里的变量

1
2
3
4
5
<!-- 这将抛出一个错误,因为“todo” property 没有在实例上定义 -->

<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo.name }}
</li>

因此要使用v-if来限制渲染列表的条件时,必须将v-for作用在v-if的父节点上,使v-for的优先级提高才行,可以使用下面介绍的<template>标签来修正

<template>标签

条件渲染和列表渲染的指令v-if v-for都需要添加到标签内才会使其或其子节点起作用,这样的特性使得两个指令使用不是那么灵活,此时就可以使用<template>标签

<template>标签可以当作一个空标签,不会再最终页面代码中出现,但是可以作为中间存放指令或使用一些逻辑的临时标签,为了使得指令可以更加灵活的使用

如上文提到可以使用<template>标签实现使用v-if来控制v-for的列表渲染

1
2
3
4
5
<template v-for="todo in todos" :key="todo.name">
<li v-if="!todo.isComplete">
{{ todo.name }}
</li>
</template>

只需要将<template>标签作为一个空标签供v-for循环其子节点,在子节点中再用v-if来控制条件即可以实现