天天看點

Vue 2.0學習筆記:v-for

上一節,我們學習了在Vue中如何通過

v-if

v-show

根據條件渲染所需要的DOM元素或者模闆。在實際的項目中,我們很多時候會碰到将JSON資料中的數組或對象渲染出清單之類的元素。在Vue中,提供了一個

v-for

的指令,可以渲染清單。

v-for

 的作用

v-for

可以基于源資料多次渲染元素或模闆塊。這個指令必須用特定的文法

alias in expression

,為目前周遊的元素提供别名:

<div v-for="alias in expression"> {{ alias }}</div>      

一般都是給數組或對象指定别名,除此之外還可以為索引值指定别名,對于對象還可以給

value

指定别名,常見的幾種情形如下:

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疊代器的文法。

v-for

的預設行為試着不改變整體,而是替換元素。迫使其重新排序的元素,你需要提供一個

key

的特殊屬性:

接下來,我們看看

v-for

的一些使用場景。

一個數組的 

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

中,在浏覽器看到的效果如下:

Vue 2.0學習筆記:v-for

上面的例子是通過

v-for

把數組

items

的每個項疊代出來放到

li

中,除此之外,還可以把數組的每個

index

也周遊出來。在上面的代碼的基礎上,咱們修改一下模闆:

1 <ul>
2     <li v-for="(item, index) in items">index-{{ index }}: {{ item }}</li>
3 </ul>      

這個時候數組的索引号也周遊出來了:

Vue 2.0學習筆記:v-for

從上面的示列看出來了,你需要哪個元素(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 2.0學習筆記:v-for

為了不會污染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 2.0學習筆記:v-for

雖然有變化了,但不是我們想要的排序結果。雖然結果不是我們想要的,但這并不是Vue自身的問題,在JavaScript中也是這樣。如果我們要想真正的實作一個排序效果,那麼需要添加一個JavaScript的數組的排序函數的功能:

function sortNumber(a, b) {
    return a - b
}      

computed

裡的代碼也做一個相應的修改:

computed: {
    sortItems: function() {
        return this.items.sort(sortNumber)
    }
}      

這相輸出的效果才真正的是一個正确的排序效果:

Vue 2.0學習筆記:v-for

有關于JavaScript中排序更多的介紹可以閱讀下面的文章:

  • 數組的

    sort()

    reverse()

    方法
  • 排序算法
  • JS中可能用得到的全部的排序算法
  • JavaScript實作資料結構中的排序算法
  • 排序圖解:JS排序算法實作

上面的例子,我們看到的是是一個簡單的純數字之類的數組,其其數組中的每個項也可以是對象,比如:

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>      

這個時候看到的效果如下:

Vue 2.0學習筆記:v-for

在JavaScript中,我們有很多數組的方法,可以對數組進行操作,這些方法可以修改一個數組。其實,在Vue中同樣包含一組觀察數組變異方法,這些方法将會觸發元素的重新更新(視圖更新),這些方法也是JavaScript中數組中常看到的方法:

push()

pop()

shift()

unshift()

splice()

sort()

reverse()

。我們可以在控制台中簡單的看一下前面的示例中

items

數組調用變異方法的效果:

Vue 2.0學習筆記:v-for

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

元素中。效果如下:

Vue 2.0學習筆記:v-for

你也可以給對象的

key

周遊出來:

<ul>
    <li v-for="(value, key) in obj">{{ key }}: {{ value }}</li>
</ul>      

效果如下:

Vue 2.0學習筆記:v-for

同樣,也可以類似數組一樣,可以把

index

索引做為第三個參數:

<ul>
    <li v-for="(value, key, index) in obj">{{ index }}. {{ key }}: {{ value }}</li>
</ul>      
Vue 2.0學習筆記:v-for

前面提到過,數組可以變異,但對于對象而言,Vue不能檢測對象屬性的添加或删除。這主要也是由于JavaScript的限制。不過在Vue中,對于已經建立好的執行個體,可以使用

Vue.set(object, key, value)

方法向嵌套對象添加響應式屬性。例如:

var app = new Vue({
    data: {
        obj: {
            name: 'Airen'
        }
    }
})      

可以使用類似下面的方式,給

obj

對象添加一個新的屬性

age

回到我們的示例中給資料源中的

obj

添加一個

'from'

key

,而且其對應的

value

值為

'江西'

Vue 2.0學習筆記:v-for

除了

Vue.set()

之外,還可以使用

app.$set

執行個體方法,它其實就是

Vue.set

的别名:

mounted(){
    this.$set(this.obj, '職位', '碼農') } 
           
Vue 2.0學習筆記:v-for
這裡用到了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> 
           

結果如下:

Vue 2.0學習筆記:v-for

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> 
           

效果如下:

Vue 2.0學習筆記:v-for

注意了,

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.js 2建立To-Do App
  • 使用Vue.js和Vuex 2.0建構一個簡單的Todo應用程式

總結

這篇文章主要總結了Vue的

v-for

指令。通過這個指令,配合資料源中的數組或者對象,我們可以很友善的生成清單。這也常常稱為清單渲染。當然配合一些模闆,我們可以做出一些特有的功能和效果。比如文章中最後一個Todo 清單,使用

v-for

很易實作。

著作權歸作者所有。

商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

原文: https://www.w3cplus.com/vue/v-for.html © w3cplus.com

轉載于:https://www.cnblogs.com/hlsy20180129/p/9277654.html

繼續閱讀