上一节,咱们学习了在Vue中如何经过v-if
和v-show
根据条件渲染所须要的DOM元素或者模板。在实际的项目中,咱们不少时候会碰到将JSON数据中的数组或对象渲染出列表之类的元素。在Vue中,提供了一个v-for
的指令,能够渲染列表。javascript
v-for
的做用v-for
能够基于源数据屡次渲染元素或模板块。这个指令必须用特定的语法alias in expression
,为当前遍历的元素提供别名:html
<div v-for="alias in expression"> {{ alias }}</div>
通常都是给数组或对象指定别名,除此以外还能够为索引值指定别名,对于对象还能够给value
指定别名,常见的几种情形以下:vue
1 <div v-for="item in items">{{ item }}</div> 2 <div v-for="(item, index) in items">{{ item }} {{ index }}</div> 3 <div v-for="val in object"></div> 4 <div v-for="(val, key) in object"></div> 5 <div v-for="(val, key, index) in object"></div>
其中咱们也能够把in
换成of
做为分隔符,由于它是最接近JavaScript迭代器的语法。java
v-for
的默认行为试着不改变总体,而是替换元素。迫使其从新排序的元素,你须要提供一个key
的特殊属性:git
<div v-for="itme in items" :key="item.id"> {{ item.text }}</div>
接下来,咱们看看v-for
的一些使用场景。github
v-for
使用v-for
指令把数组的选项列表进行渲染。v-for
指令须要使用item in items
形式的特殊语法,items
是源数据数组,item
是数组元素迭代的别名。来看一个简单的示例:算法
1 <!-- Template --> 2 <ul> 3 <li v-for="item in items">{{ item }}</li> 4 </ul> 5 6 // JavaScript 7 var app = new Vue({ 8 el: '#app', 9 data: { 10 items: [1, 34, 89, 92, 45, 76, 33] 11 } 12 })
这个时候,数组items
的每一个item
渲染到对应的li
中,在浏览器看到的效果以下:sql
上面的例子是经过v-for
把数组items
的每一个项迭代出来放到li
中,除此以外,还能够把数组的每一个index
也遍历出来。在上面的代码的基础上,我们修改一下模板:express
1 <ul> 2 <li v-for="(item, index) in items">index-{{ index }}: {{ item }}</li> 3 </ul>
这个时候数组的索引号也遍历出来了:api
从上面的示列看出来了,你须要哪一个元素(HTML的标签)循环,那么v-for
就写在那个元素上。
上面咱们已经能够正常的使用v-for
将定义的数组每一项输出来。为了加深学习,我们在上面的示例基础上增长一项需求,就是对输出的数组进行排序。这个时候,我们须要使用到Vue中的computed
属性。那么computed
属性是作什么的,我也不清楚,我们一块儿先不去了解他吧,记做Vue有这么一个属性。随着后面的学习,咱们会明白computed
的用处的。
在Vue中,咱们不能污染源数据,若是咱们直接对源数据items
经过sort()
方法进行排序,将会报错的:
1 var app = new Vue({ 2 el: '#app', 3 computed: { 4 items: function() { 5 return this.items.sort() 6 } 7 }, 8 data: { 9 items: [1, 34, 89, 92, 45, 76, 33] 10 } 11 })
为了避免会污染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] } })
这个时候,咱们的模板也须要作对应的修改:
1 <ul> 2 <li v-for="item in sortItems">{{ item }}</li> 3 </ul>
若是不出意外的话,你看到的效果将是这样的:
虽然有变化了,但不是咱们想要的排序结果。虽然结果不是咱们想要的,但这并非Vue自身的问题,在JavaScript中也是这样。若是咱们要想真正的实现一个排序效果,那么须要添加一个JavaScript的数组的排序函数的功能:
function sortNumber(a, b) { return a - b }
把computed
里的代码也作一个相应的修改:
computed: { sortItems: function() { return this.items.sort(sortNumber) } }
这相输出的效果才真正的是一个正确的排序效果:
有关于JavaScript中排序更多的介绍能够阅读下面的文章:
上面的例子,咱们看到的是是一个简单的纯数字之类的数组,其其数组中的每一个项也能够是对象,好比:
data: { objItems: [ { firstName: 'Jack', lastName: 'Li', age: 34 }, { firstName: 'Airen', lastName: 'Liao', age: 18 } ] }
咱们把模板换成:
1 <li v-for="objItem in objItems">{{ objItem.firstName }} {{objItem.lastName}} is {{ objItem.age}} years old!</li>
这个时候看到的效果以下:
在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
相同的效果,同时也将触发状态更新:
1 Vue.set(app.items, indexOfItem, newValue) 2 3 app.items.splice(indexOfItem, 1, newValue)
为了解决第二类问题,你可使用splice()
:
app.items.splice(newLength)
v-for
v-for
除了可使用在数组上以外还能够应用在对象上。
1 <!-- Template --> 2 <ul> 3 <li v-for="value in obj">{{ value }}</li> 4 </ul> 5 6 // JavaScript 7 obj: { 8 firstName: 'Airen', 9 lastName: 'Liao', 10 age: 30 11 }
使用v-for
能够把obj
的每一个key
对应的value
值遍历出来,而且填到对应的li
元素中。效果以下:
你也能够给对象的key
遍历出来:
<ul> <li v-for="(value, key) in obj">{{ key }}: {{ value }}</li> </ul>
效果以下:
一样,也能够相似数组同样,能够把index
索引作为第三个参数:
<ul> <li v-for="(value, key, index) in obj">{{ index }}. {{ key }}: {{ value }}</li> </ul>
前面提到过,数组能够变异,但对于对象而言,Vue不能检测对象属性的添加或删除。这主要也是因为JavaScript的限制。不过在Vue中,对于已经建立好的实例,可使用Vue.set(object, key, value)
方法向嵌套对象添加响应式属性。例如:
var app = new Vue({ data: { obj: { name: 'Airen' } } })
可使用相似下面的方式,给obj
对象添加一个新的属性age
:
Vue.set(app.obj, 'age', 27)
回到咱们的示例中给数据源中的obj
添加一个'from'
的key
,并且其对应的value
值为'江西'
:
除了Vue.set()
以外,还可使用app.$set
实例方法,它其实就是Vue.set
的别名:
mounted(){
this.$set(this.obj, '职位', '码农') }
这里用到了Vue中的
mounted()
,和computed
同样,也不知道他在Vue中的做用,一样放到后面来。咱们老是会搞明白的。
有时候你可能须要为已有对象赋予多个新属性,好比使用Object.assign()
或_.extend()
。在这种状况下,应该用两个对象的属性建立一个新的对象。因此,若是你想添加新的响应式属性,不要像这样:
Object.assign(this.obj, { age: 27, favoriteColor: 'Vue Green' })
应该这样作:
this.obj = Object.assign({}, this.obj, { age: 27, favoriteColor: 'Vue Green' })
v-for
v-for
也能够取整数。在这种状况下,它将重复屡次模板:
<ul> <li v-for="n in 10">{{ n }}</li> </ul>
结果以下:
v-for
和 一个 <template>
相似于v-if
,你也能够利用带有v-for
的<template>
渲染多个元素,好比:
<ul> <template v-for="(value, key) in obj"> <li> <label :for="key">{{ key }}:</label> <input type="text" :placeholder="value" :id="key" /> </li> </template> </ul>
效果以下:
注意了,v-for
和<template>
一块儿使用的时候,须要把v-for
写在<template>
元素上。另外上面的示例中,我们还使用了Vue的一些其余特性,但这些特性不是这节内容所要学习的。后面咱们会有机会一一介绍的。
v-for
在自定义组件里,也能够像任何普通元素同样用v-for
。
<my-component v-for="item in items" :key="item.id"></my-component>
2.2.0+ 的版本里,当在组件中使用
v-for
时,key
如今是必须的。
然而他不能自动传递数据到组件里,由于组件有本身独立的做用域。为了传递迭代数据到组件里,咱们要用 props
:
1 <my-component 2 v-for="(item, index) in items" 3 v-bind:item="item" 4 v-bind:index="index" 5 v-bind:key="item.id" 6 ></my-component>
不自动注入 item
到组件里的缘由是,由于这使得组件会与 v-for
的运做紧密耦合。在一些状况下,明确数据的来源可使组件可重用。
来看一个简单的Todo示例:
1 <div id="todo"> 2 <input 3 v-model="newTodoText" 4 v-on:keyup.enter="addNewTodo" 5 placeholder="Add a todo" 6 /> 7 8 <ul> 9 <li 10 is="todoItem" 11 v-for="(todo, index) in todos" 12 v-bind:title="todo" 13 v-on:remove="todos.splice(index, 1)"></li> 14 </ul> 15 </div> 16 17 Vue.component('todoItem', { 18 template:` 19 <li> 20 {{ title }} 21 <button v-on:click="$emit('remove')">x</button> 22 </li> 23 `, 24 props: ['title'] 25 }) 26 27 new Vue({ 28 el: '#todo', 29 data: { 30 newTodoText: '', 31 todos: [ 32 'Do the dishes', 33 'Take out the trash', 34 'Mow the lawn' 35 ] 36 }, 37 methods: { 38 addNewTodo: function() { 39 this.todos.push(this.newTodoText) 40 this.newTodoText = '' 41 } 42 } 43 })
若是你和我同样,对里示例不能理解透彻,不用担忧,饭须要一口一口吃。若是你想急着了解清楚的话,能够阅读下面的文章:
这篇文章主要总结了Vue的v-for
指令。经过这个指令,配合数据源中的数组或者对象,咱们能够很方便的生成列表。这也经常称为列表渲染。固然配合一些模板,咱们能够作出一些特有的功能和效果。好比文章中最后一个Todo 列表,使用v-for
很易实现。
著做权归做者全部。
商业转载请联系做者得到受权,非商业转载请注明出处。
原文: https://www.w3cplus.com/vue/v-for.html © w3cplus.com