Vue 2.0學習筆記:v-for

上一節,咱們學習了在Vue中如何經過v-ifv-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) 

有關於JavaScript中數組相關的內容能夠點擊這裏這裏

對象的 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 })
View Code

 

 

若是你和我同樣,對裏示例不能理解透徹,不用擔憂,飯須要一口一口吃。若是你想急着瞭解清楚的話,能夠閱讀下面的文章:

總結

這篇文章主要總結了Vue的v-for指令。經過這個指令,配合數據源中的數組或者對象,咱們能夠很方便的生成列表。這也經常稱爲列表渲染。固然配合一些模板,咱們能夠作出一些特有的功能和效果。好比文章中最後一個Todo 列表,使用v-for很易實現。

著做權歸做者全部。
商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
原文: https://www.w3cplus.com/vue/v-for.html © w3cplus.com

相關文章
相關標籤/搜索