vue裏面的v-for列表循環

列表渲染

v-for

v-for能夠把數據中的一個數組對應爲一組元素
v-for 指令須要以 item in items 形式的特殊語法, items 是源數據數組而且 item 是數組元素迭代的別名。html

<li v-for="item in items">{{item.text}}</li>
data:{
    items:[
        {text:"第一組"},
        {text:"第二組"},
        {text:"第三組"},
    ]
}

輸出HTMLes6

第一組
第二組
第三組

在 v-for 塊中,咱們擁有對父做用域屬性的徹底訪問權限。 v-for 還支持一個可選的第二個參數爲當前項的索引。數組

<li v-for="(item, index) in items">
    {{ index }} - {{ item.text }}
</li>

輸出HTML性能

1 - 第一組
2 - 第二組
3 - 第三組

你也能夠用 of 替代 in 做爲分隔符,由於它是最接近 JavaScript 迭代器的語法:this

<li v-for="item of items">
    {{ item.text }}
</li>

一個對象的 v-for

你也能夠用 v-for 經過一個對象的屬性來迭代。spa

<li v-for="item of items">
    {{item}}
</li>
data:{
    items:{
        text1:"第一組",
        text2:"第二組",
        text3:"第三組",
    }
}

輸出HTMLprototype

第一組
第二組
第三組

你也能夠提供第二個的參數爲鍵名:code

<li v-for="(item,key) of items">
    {{key}} : {{item}}
</li>

輸出HTMLcomponent

text1 : 第一組
text2 : 第二組
text3 : 第三組

第三個參數爲索引:htm

<li v-for="(item,key,index) of items">
    {{index}} . {{key}} : {{item}}
</li>

輸出HTML

0 . text1 : 第一組
1 . text2 : 第二組
2 . text3 : 第三組

key

當 Vue.js 用 v-for 正在更新已渲染過的元素列表時,它默認用 「就地複用」 策略。若是數據項的順序被改變,Vue將不是移動 DOM 元素來匹配數據項的順序, 而是簡單複用此處每一個元素,而且確保它在特定索引下顯示已被渲染過的每一個元素。這個相似 Vue 1.x 的 track-by="$index" 。

這個默認的模式是高效的,可是隻適用於不依賴子組件狀態或臨時 DOM 狀態(例如:表單輸入值)的列表渲染輸出。

爲了給 Vue 一個提示,以便它能跟蹤每一個節點的身份,從而重用和從新排序現有元素,你須要爲每項提供一個惟一 key 屬性。理想的 key 值是每項都有的且惟一的 id。這個特殊的屬性至關於 Vue 1.x 的 track-by ,但它的工做方式相似於一個屬性,因此你須要用 v-bind 來綁定動態值(在這裏使用簡寫):

<div v-for="item in items" :key="item.id">
  <!-- 內容 -->
</div>

建議儘量使用 v-for 來提供 key ,除非 DOM 內容遍歷起來很是簡單,或者你是有意識的要依賴於默認行爲以便得到性能提高。
由於它是 Vue 識別節點的一個通用機制, key 並不特別與 v-for 關聯,key 還具備其餘用途,咱們將在後面的指南中看到其餘用途。

一個組件的v-for

2.2.0+ 的版本里,當在組件中使用 v-for 時,key 如今是必須的。

在自定義組件裏,你能夠像任何普通元素同樣用 v-for 。

<mycom v-for="(item,index) in todo" :key="index"></mycom>
Vue.component('mycom', {
  template: "<h1>瘋狂的石頭</h1>"
})
var vm = new Vue({
    el:"#box",
    data:{
        todo:[
            {text:1,ok:true},
            {text:2,ok:false},
            {text:3,ok:true},   
        ]  
    }   
})
瘋狂的石頭
瘋狂的石頭
瘋狂的石頭

可是咱們又如何將數據渲染到咱們的組件中呢?如今咱們就須要綁定一個屬性,屬性須要在組件中註冊

<mycom v-for="(item,index) in todo" :key="index" :lie="item.text"></mycom>
Vue.component('mycom', {
  template: "<h1>瘋狂的石頭{{this.lie}}</h1>",
  props:["lie"]
})
var vm = new Vue({
    el:"#box",
    data:{
        todo:[
            {text:1,ok:true},
            {text:2,ok:false},
            {text:3,ok:true},   
        ]  
    }   
})

輸出HTML

瘋狂的石頭1
瘋狂的石頭2
瘋狂的石頭3

v-for 與 < template >

咱們也可使用 v-for 來渲染 < template >標籤。例如:

<template v-for="item in todo">
    <div>{{ item.text }}</div>
</template>
data:{
    todo:[
        {text:1,ok:true},
        {text:2,ok:false},
        {text:3,ok:true},   
    ]  
}

輸出HTML

1
2
3

數組更新檢測

變異方法

變異方法(mutation method),顧名思義,會改變被這些方法調用的原始數組。

Vue 包含一組觀察數組的變異方法,因此它們也將會觸發視圖更新。這些方法以下:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()

非變異方法

相非變異(non-mutating method)方法,例如: filter(), concat() 和 slice() 。這些不會改變原始數組,但老是返回一個新數組。當使用非變異方法時,能夠用新數組替換舊數組:

example1.items = example1.items.filter(function (item) {
    return item.message.match(/Foo/)
})

你可能認爲這將致使 Vue 丟棄現有 DOM 並從新渲染整個列表。幸運的是,事實並不是如此。 Vue 爲了使得 DOM 元素獲得最大範圍的重用而實現了一些智能的、啓發式的方法,因此用一個含有相同元素的數組去替換原來的數組是很是高效的操做。

注意事項

因爲 JavaScript 的限制, Vue 不能檢測如下變更的數組:

  • 當你利用索引直接設置一個項時,例如: vm.items[indexOfItem] = newValue

  • 當你修改數組的長度時,例如: vm.items.length = newLength

爲了解決第一類問題,如下兩種方式均可以實現和 vm.items[indexOfItem] = newValue 相同的效果, 同時也將觸發狀態更新:

Vue.set(example1.items, indexOfItem, newValue)
// Array.prototype.splice
example1.items.splice(indexOfItem, 1, newValue)

爲了解決第二類問題,你可使用 splice:

example1.items.splice(newLength)

對象更新檢測

咱們能夠用如下三種方法對對象進行更新:

若是你須要爲對象屬性之中添加新的屬性,那麼我麼你能夠利用如下兩種方法

Vue.set("目標對象","屬性","值")
vm.$set("目標對象","屬性","值")

若是咱們想更新對象中的屬性,如下這種方法能夠知足你

this.userProfile = Object.assign({}, this.userProfile, {
    age: 27,
    favoriteColor: 'Vue Green'
})
this.userProfile   //對象自己的屬性

Object.assign()    //es6新增長的方法,用來將源對象的全部可枚舉屬性,複製到目標對象。它至少須要兩個對象做爲參數,第一個參數是目標對象,後面的參數都是源對象

{}                 //你須要增長的屬性

若是目標對象與源對象有同名屬性,或多個源對象有同名屬性,則後面的屬性會覆蓋前面的屬性。
  • 注意!咱們不更改根屬性的屬性,只能更改跟屬性如下的子屬性的屬性

顯示過濾 / 排序結果

有時,咱們想要顯示一個數組的過濾或排序副本,而不實際改變或重置原始數據。在這種狀況下,能夠建立返回過濾或排序數組的計算屬性。

<!-- 取到 numbers 裏面的偶數位的值 -->
<li v-for="n in evenNumbers">{{ n }}</li>
data: {
    numbers: [ 1, 2, 3, 4, 5 ]
},
computed: {
    evenNumbers: function () {
        return this.numbers.filter(function (number) {
        return number % 2 === 0
        })
    }
}

在計算屬性不適用的狀況下 (例如,在嵌套 v-for 循環中) 你可使用一個 method 方法:

<li v-for="n in even(numbers)">{{ n }}</li>
data: {
    numbers: [ 1, 2, 3, 4, 5 ]
},
methods: {
    even: function (numbers) {
        return numbers.filter(function (number) {
        return number % 2 === 0
        })
    }
}

一段取值範圍的 v-for

v-for 也能夠取整數。在這種狀況下,它將重複屢次模板。

<div>
    <span v-for="n in 10">{{ n }} </span>
</div>

輸出HTML

1 2 3 4 5 6 7 8 9 10
相關文章
相關標籤/搜索