Vue 3.x 列表渲染 v-for 指令使用方法
2022年8月 · 预计阅读时间: 4 分钟
这篇文章我们来看一下在 vue 中展示列表内容。在前端开发中,经常会有展示列表的需求,例如博客列表,任务列表等等,那么 vue 中提供了 v-for 指令,来让我们方便的展示列表数据。
展示纯数组数据
我们知道,data() 函数返回的对象中,它的属性可以是任何类型,那么要展示列表数据,最合适的就是数组类型了:
data() {
return {
todos: ["把项目做完", "去超市购物", "看10分钟的书"],
};
},
假设我们要把 todos (待办事项)数组渲染到由 ul 和 li 构成的无序列表中,那么我们可以先定好结构:
<div id="app">
<ul>
<li></li>
</ul>
</div>
这里,ul 只需要渲染一次,而 todo 内容需要通过重复多次 li 标签来进行渲染:
<div id="app">
<ul>
<li>把项目做完</li>
<li>去超市购物</li>
<li>看10分钟的书</li>
</ul>
</div>
而使用 vue 提供的 v-for 指令,则可以只写一个 li 标签,在它里边使用 v-for 属性遍历 todos 数组:
<ul>
<li v-for="todo in todos">{{ todo }}</li>
</ul>
v-for 指令后面的值可以认为是一个 JavaScript 表达式,跟 for...in 循环类似,在关键字 in 的后面是要遍历的数组,前边则是给每个数组元素起的变量名字,可以在 li 开合标签中间,使用两个大括号引用,这样就根据数组的长度,生成了对应数量的 li 元素。
访问索引
如果想在遍历的时候,访问当前遍历的索引,那么我们可以在 in 的前边,在定义一个变量,例如叫作 index,放到 todo 变量的后面,并用逗号隔开,最后再使用小括号括起来:
<li v-for="(todo, index) in todos">{{index}}. {{ todo }}</li>
这样可以直接在后面访问 index 变量访问索引,不过索引是从 0 开始的,如果想让它从 1 开始显示,那么可以直接在两个大括号之间使用 JavaScript 表达式,给 index + 1:
{{ index + 1 }}
是的,vue 的 html 模板插值或者指令中,可以直接使用 JavaScript 表达式。
展示对象数组数据
如果要在 v-for 中遍历数组对象,也就是由对象构成的数组:
data() {
return {
todos: [
{
content: "把项目做完",
complete: true,
},
{
content: "去超市购物",
complete: false,
},
{
content: "看10分钟的书",
complete: false,
},
],
};
},
那么可以使用同样的方法,使用 v-for 遍历,只是在模板插值中访问对象中的内容时,需要使用对象访问语法,跟在 JavaScript 中访问对象一样:
<li v-for="todo in todos">
<input type="checkbox" :checked="todo.complete" />{{todo.content}}
</li>
示例
好,在介绍完 v-for 的用法之后,我们来看一个具体的示例。这里我们渲染一个待办事项列表。还是使用之前我们创建好的 vue 模板项目,在 index.js 中,我们先定义一个普通数组 todos:
const app = Vue.createApp({
data() {
return {
todos: ["把项目做完", "去超市购物", "看10分钟的书"],
};
},
});
app.mount("#app");
里边有三项待办事项,接下来打开 index.html 文件,在 id 为 app 的 div 中,定义一个 ul 无序列表,然后在里边定义一个 li 元素,在 li 元素里边,我们使用 v-for 指令,这里:
- v-for 指令的值我们写上 todo in todos。
- todos 就是要遍历的数组,todo 是给遍历到的数组元素起个名字,方便后面引用。
- li 开合标签中间,使用模板插值语法,两个大括号,引用 todo 变量的值。
<ul>
<li v-for="todo in todos">{{ todo }}</li>
</ul>
这样就渲染出了待办事项列表。
访问索引
如果要给待办事项加上序号,可以在 v-for 指令中获取当前遍历到的索引:
<li v-for="(todo, index) in todos">{{index + 1}}. {{ todo }}</li>
这里直接在 todo 后面,加上一个逗号,再定义一个 index 变量,这个名字可以随便起,它就是当前遍历到的索引,别忘了把这两个变量放到一个小括号里。后面在模板插值中,可以直接给 index 加 1,让序号从 1 开始。这样就渲染了带序号的待办事项列表。
遍历对象数组
如果待办事项是通过对象的形式定义的,它有待办事项内容 content 和是否已完成 complete 两个属性,例如这样一组数据:
data() {
return {
todos: [
{
content: "把项目做完",
complete: true,
},
{
content: "去超市购物",
complete: false,
},
{
content: "看10分钟的书",
complete: false,
},
],
};
},
并且呢,在 html 中,我们根据待办是否已完成,来显示复选框,如果已完成,那么复选框会打勾,如果没有完成,那么复选框则是未选中的状态。那么我们先在 li 中,定义一个复选框:
<li v-for="todo in todos"><input type="checkbox" />{{ todo }}</li>
这个时候,遍历到的 todo 是一个对象了,如果直接使用 {{ todo }}
会直接把整个对象转换成字符串进行展示,这时我们可以直接使用 todo.content 来访问 todo 对象的 content 属性值,跟在 JavaScript 中访问对象是一样的:
<li v-for="todo in todos"><input type="checkbox" />{{ todo.content }}</li>
现在,todo 的内容显示出来了,但是复选框还没有根据 todo 是否已完成,来显示选中或未选中状态。我们知道,在普通的 html 中,要让一个复选框变为选中状态,只需要给它加一个 checked 属性:
<input type="checkbox" checked />
我们需要根据 todo 的 complete 属性值来决定要不要添加 checked 这个属性。这就需要用到之前学习的 v-bind 指令了,不过,这里的 checked 似乎只有一个属性名,但是没有属性值,那要怎么绑定呢?其实这种单独属性名的形式,就相当于值为 true:
<input type="checkbox" checked="true" />
如果没有这个属性,那么就相当于这个属性值为 false:
<input type="checkbox" checked="false" />
那么根据这个特点,我们可以使用 v-bind 或简写形式,直接把 todo 的 complete 的属性值,绑定到 checked 属性:
<li v-for="todo in todos">
<input type="checkbox" :checked="todo.complete" />{{todo.content}}
</li>
这样,复选框就会根据 todo 的 complete 属性值,来展示为选中状态或未选中状态了。
小结
这个就是在 vue 中展示列表数据的方法,使用 v-for 指令,遍历 data 中数组类型的属性,并且还可以访问索引和遍历对象数组。另外对于 vue 的模板,在插值中可以直接使用 JavaScript 表达式,对某个变量进行数学运算,或访问对象类型的变量。对于只有单独的一个属性名的情况,也利用 v-bind 进行数据绑定。