上一節,咱們學習了在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