广告:宝塔Linux面板高效运维的服务器管理软件 点击【 https://www.bt.cn/p/uNLv1L 】立即购买
之前的文章中,我们学习了在Vue中如何通过v-if
和v-show
根据条件渲染所需要的DOM元素或者模板。在实际的项目中,我们很多时候会碰到将JSON数据中的数组或对象渲染出列表之类的元素。在Vue中,提供了一个v-for
的指令,可以渲染列表。(学习视频分享:vue视频教程)
v-for
的作用v-for
可以基于源数据多次渲染元素或模板块。这个指令必须用特定的语法alias in expression
,为当前遍历的元素提供别名:
<div v-for="alias in expression"> {{ alias }}</div>登录后复制
一般都是给数组或对象指定别名,除此之外还可以为索引值指定别名,对于对象还可以给value
指定别名,常见的几种情形如下:
<div v-for="item in items">{{ item }}</div><div v-for="(item, index) in items">{{ item }} {{ index }}</div><div v-for="val in object"></div><div v-for="(val, key) in object"></div><div v-for="(val, key, index) in object"></div>登录后复制
其中我们也可以把in
换成of
作为分隔符,因为它是最接近JavaScript迭代器的语法。
v-for
的默认行为试着不改变整体,而是替换元素。迫使其重新排序的元素,你需要提供一个key
的特殊属性:
<div v-for="itme in items" :key="item.id"> {{ item.text }}</div>登录后复制
接下来,我们看看v-for
的一些使用场景。
v-for
使用v-for
指令把数组的选项列表进行渲染。v-for
指令需要使用item in items
形式的特殊语法,items
是源数据数组,item
是数组元素迭代的别名。来看一个简单的示例:
<!-- Template --><ul> <li v-for="item in items">{{ item }}</li></ul>// JavaScriptvar app = new Vue({ el: '#app', data: { items: [1, 34, 89, 92, 45, 76, 33] }})登录后复制
这个时候,数组items
的每个item
渲染到对应的li
中,在浏览器看到的效果如下:
上面的例子是通过v-for
把数组items
的每个项迭代出来放到li
中,除此之外,还可以把数组的每个index
也遍历出来。在上面的代码的基础上,咱们修改一下模板:
<ul> <li v-for="(item, index) in items">index-{{ index }}: {{ item }}</li></ul>登录后复制
这个时候数组的索引号也遍历出来了:
从上面的示列看出来了,你需要哪个元素(HTML的标签)循环,那么v-for
就写在那个元素上。
上面我们已经可以正常的使用v-for
将定义的数组每一项输出来。为了加深学习,咱们在上面的示例基础上增加一项需求,就是对输出的数组进行排序。这个时候,咱们需要使用到Vue中的computed
属性。
在Vue中,我们不能污染源数据,如果我们直接对源数据items通过sort()方法进行排序,将会报错的:
var app = new Vue({ el: '#app', computed: { items: function() { return this.items.sort() } }, data: { items: [1, 34, 89, 92, 45, 76, 33] }})登录后复制
为了不会污染Vue中的源数据,需要在computed
里重新声明一个对象,比如声明一个sortItems
对象:
var app = new Vue({ el: '#app', computed: { sortItems: function() { return this.items.sort() } }, data: { items: [1, 34, 89, 92, 45, 76, 3, 12] }})登录后复制
这个时候,我们的模板也需要做对应的修改:
<ul> <li v-for="item in sortItems">{{ item }}</li></ul>登录后复制
如果不出意外的话,你看到的效果将是这样的:
虽然有变化了,但不是我们想要的排序结果。虽然结果不是我们想要的,但这并不是Vue自身的问题,在JavaScript中也是这样。如果我们要想真正的实现一个排序效果,那么需要添加一个JavaScript的数组的排序函数的功能:
function sortNumber(a, b) { return a - b}登录后复制
把computed
里的代码也做一个相应的修改:
computed: { sortItems: function() { return this.items.sort(sortNumber) }}登录后复制
这相输出的效果才真正的是一个正确的排序效果:
上面的例子,我们看到的是是一个简单的纯数字之类的数组,其其数组中的每个项也可以是对象,比如:
<div v-for="item in items">{{ item }}</div><div v-for="(item, index) in items">{{ item }} {{ index }}</div><div v-for="val in object"></div><div v-for="(val, key) in object"></div><div v-for="(val, key, index) in object"></div>0登录后复制
我们把模板换成:
<div v-for="item in items">{{ item }}</div><div v-for="(item, index) in items">{{ item }} {{ index }}</div><div v-for="val in object"></div><div v-for="(val, key) in object"></div><div v-for="(val, key, index) in object"></div>1登录后复制
这个时候看到的效果如下:
在JavaScript中,我们有很多数组的方法,可以对数组进行操作,这些方法可以修改一个数组。其实,在Vue中同样包含一组观察数组变异方法,这些方法将会触发元素的重新更新(视图更新),这些方法也是JavaScript中数组中常看到的方法:push()
、pop()
、shift()
、unshift()
、splice()
、sort()
、reverse()
。我们可以在控制台中简单的看一下前面的示例中items
数组调用变异方法的效果:
Vue不但提供了数组变异的方法,还提供了替换数组的方法。变异方法可以通过些方法的调用修改源数据中的数组;除此之外也有对应的非变异方法,比如filter()
、concat()
和slice()
等。这些方法是不会改变源数据中的原始数组,但总是返回一个新数组。当使用这些方法时,可以用新数组替换旧数组。
由于JavaScript的限制,Vue不能检测以下变动的数组:
当你利用索引直接设置一个项时,例如app.items[indexOfItem] = newValue
当你修改数组的长度时,例如: app.items.length = newLength
为了解决第一类问题,以下两种方式都可以实现和app.items[indexOfItem = newValue
相同的效果,同时也将触发状态更新:
<div v-for="item in items">{{ item }}</div><div v-for="(item, index) in items">{{ item }} {{ index }}</div><div v-for="val in object"></div><div v-for="(val, key) in object"></div><div v-for="(val, key, index) in object"></div>2登录后复制
为了解决第二类问题,你可以使用splice()
:
<div v-for="item in items">{{ item }}</div><div v-for="(item, index) in items">{{ item }} {{ index }}</div><div v-for="val in object"></div><div v-for="(val, key) in object"></div><div v-for="(val, key, index) in object"></div>3登录后复制对象的
v-for
v-for
除了可以使用在数组上之外还可以应用在对象上。
<div v-for="item in items">{{ item }}</div><div v-for="(item, index) in items">{{ item }} {{ index }}</div><div v-for="val in object"></div><div v-for="(val, key) in object"></div><div v-for="(val, key, index) in object"></div>4登录后复制
使用v-for
可以把obj
的每个key
对应的value
值遍历出来,并且填到对应的li
元素中。效果如下:
你也可以给对象的key
遍历出来:
<div v-for="item in items">{{ item }}</div><div v-for="(item, index) in items">{{ item }} {{ index }}</div><div v-for="val in object"></div><div v-for="(val, key) in object"></div><div v-for="(val, key, index) in object"></div>5登录后复制
效果如下:
同样,也可以类似数组一样,可以把index
索引做为第三个参数:
<div v-for="item in items">{{ item }}</div><div v-for="(item, index) in items">{{ item }} {{ index }}</div><div v-for="val in object"></div><div v-for="(val, key) in object"></div><div v-for="(val, key, index) in object"></div>6登录后复制
前面提到过,数组可以变异,但对于对象而言,Vue不能检测对象属性的添加或删除。这主要也是由于JavaScript的限制。不过在Vue中,对于已经创建好的实例,可以使用Vue.set(object, key, value)
方法向嵌套对象添加响应式属性。例如:
<div v-for="item in items">{{ item }}</div><div v-for="(item, index) in items">{{ item }} {{ index }}</div><div v-for="val in object"></div><div v-for="(val, key) in object"></div><div v-for="(val, key, index) in object"></div>7登录后复制
可以使用类似下面的方式,给obj
对象添加一个新的属性age
:
<div v-for="item in items">{{ item }}</div><div v-for="(item, index) in items">{{ item }} {{ index }}</div><div v-for="val in object"></div><div v-for="(val, key) in object"></div><div v-for="(val, key, index) in object"></div>8登录后复制
回到我们的示例中给数据源中的obj
添加一个'from'
的key
,而且其对应的value
值为'江西'
:
除了Vue.set()
之外,还可以使用app.$set
实例方法,它其实就是Vue.set
的别名:
<div v-for="item in items">{{ item }}</div><div v-for="(item, index) in items">{{ item }} {{ index }}</div><div v-for="val in object"></div><div v-for="(val, key) in object"></div><div v-for="(val, key, index) in object"></div>9登录后复制
这里用到了Vue中的
mounted()
,和computed
一样,也不知道他在Vue中的作用,同样放到后面来。我们总是会搞明白的。
有时候你可能需要为已有对象赋予多个新属性,比如使用Object.assign()
或_.extend()
。在这种情况下,应该用两个对象的属性创建一个新的对象。所以,如果你想添加新的响应式属性,不要像这样:
<div v-for="itme in items" :key="item.id"> {{ item.text }}</div>0登录后复制
应该这样做:
<div v-for="itme in items" :key="item.id"> {{ item.text }}</div>1登录后复制一段取值范围的
v-for
v-for
也可以取整数。在这种情况下,它将重复多次模板:
<div v-for="itme in items" :key="item.id"> {{ item.text }}</div>2登录后复制
结果如下:
v-for
和 一个 <template>
类似于v-if
,你也可以利用带有v-for
的<template>
渲染多个元素,比如:
<div v-for="itme in items" :key="item.id"> {{ item.text }}</div>3登录后复制
效果如下:
注意了,v-for
和<template>
一起使用的时候,需要把v-for
写在<template>
元素上。另外上面的示例中,咱们还使用了Vue的一些其他特性,但这些特性不是这节内容所要学习的。后面我们会有机会一一介绍的。
v-for
在自定义组件里,也可以像任何普通元素一样用v-for
。
<div v-for="itme in items" :key="item.id"> {{ item.text }}</div>4登录后复制
2.2.0+ 的版本里,当在组件中使用
v-for
时,key
现在是必须的。
然而他不能自动传递数据到组件里,因为组件有自己独立的作用域。为了传递迭代数据到组件里,我们要用 props
:
<div v-for="itme in items" :key="item.id"> {{ item.text }}</div>5登录后复制
不自动注入 item
到组件里的原因是,因为这使得组件会与 v-for
的运作紧密耦合。在一些情况下,明确数据的来源可以使组件可重用。
来看一个简单的Todo示例:
<div v-for="itme in items" :key="item.id"> {{ item.text }}</div>6登录后复制总结
这篇文章主要总结了Vue的v-for
指令。通过这个指令,配合数据源中的数组或者对象,我们可以很方便的生成列表。这也常常称为列表渲染。当然配合一些模板,我们可以做出一些特有的功能和效果。比如文章中最后一个Todo 列表,使用v-for
很易实现。
(学习视频分享:web前端开发、编程基础视频)
以上就是详解Vue渲染列表指令:v-for的详细内容,更多请关注9543建站博客其它相关文章!
发表评论