Vue列表渲染

用v-for把一個數組對應爲一個組件元素

我們用v-for指令根據一組數組的選項列表進行渲染。v-for指令需要使用item in items形式的語法:

<ul>
    <li v-for="item in items">
        {{ item.message }}
    </li>
</ul>

var vm = new Vue({
    el: '#el',
    data: {
        items: [
            {message: 'foo'},
            {message: 'boar'}
        ]
    }
})

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

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

var vm = new Vue({
    el: '#el',
    data: {
        items: [
            {message: 'foo'},
            {message: 'bar'}
        ]
    }
})

也可以用of替代in作爲分隔符,因爲它是最接近JavaScript迭代器的語法:

<div v-for="item of items"></div>

一個對象的v-for

也可以使用v-for通過對一個對象的屬性迭代。

new Vue({
    el: '#el',
    data: {
        object: {
            firstName: 'h',
            lastName: 'z',
            age: 26
        }
    }
})

<ul id="v-for-object" class="demo">
    <li v-for="value on object">
        {{ value }}
    /li>
</ul>

也可以提供第二個參數爲名:

<div v-for="(value, key) in object">
    {{ key }} : {{ value }}
</div>

第三個參數爲索引:

<div v-for="(value, key, index) in object">
    {{index}}. {{key}}: {{value}}
</div>

Key

當Vue使用v-for正在更新已渲染過的元素列表時,它默認就地複用。如果數據項的順序被改變,Vue將不會移動DOM元素來匹配數據項的順序,而是簡單的複用此處每個元素,並且 確保它在特定索引下顯示已被渲染過的每個元素。

這個默認的模式是高效的,但只適用於不依賴子組件狀態或零時DOM狀態的列表渲染輸出。

爲了給Vue一個提示,以便追蹤每個節點的身份,從而重用和重新排序現有元素,你需要爲每項提供一個唯一key屬性。理想的key值是每項都有唯一id。它的工作方式類似於一個屬性,所以你需要用v-bind來綁定動態值:

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

建議儘可能在使用v-for時提供key,除非遍歷輸出的DOM內容非常簡單,或者是刻意依賴默認行爲以獲取性能上提升。

數組更新檢測

(1)變異方法
Vue包含一組觀察數組的變異方法,所以它們也將會觸發視圖更新。這些方法如下:

push()
pop()
shift()
unshift()
splice()
sort()
reverse()

(2)替換數組
變異方法,是會改變被這些方法調用的原始數組。相比之下也有非變異方法:

filter()
concat()
slice()

這些方法不會改變原始數組,但是總會返回一個新數組。當使用非變異方法時,可以用新數組替換舊數組:

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

你可能認爲這將導致Vue丟棄現有DOM並重新渲染整個列表。Vue爲了使得DOM得到最大範圍的重用而實現了一些智能的、啓發式的方法,所以用一個含有相同元素的數組去替換原來的數組是非常高效的操作。

注意事項

由於JavaScript的限制,Vue補鞥呢檢測以下變動的數組:

1. 當你用索引直接設置一個項的時候:vm.items[indexOfItem] = newValue
2. 當你修改數組的長度時,例如:vm.items.length = newLenth

舉個例子:

var vm = new Vue({
    data: {
        items: ['a','b','c']
    }
})
vm.items[1] = 'x' //不是響應式的
vm.items.length = 2// 不是響應式的

爲了解決第一類問題,以下兩種方式都可以實現vm.items[i] = newVal相同的效果,同時也會觸發響應式更新:

//Vue.set
Vue.set(vm.items, i, newVal)

//Array.prototype.splice
vm.items.splice(i, 1, newVal)

也可以使用vm.$set實例方法,該方法是全局方法Vue.set的一個別名:

vm.$set(vm.items, i, newVal)

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

vm.items.splice(newLenght)

對象更改檢測注意事項

由於JavaScript的限制,Vue不能檢測對象屬性的添加或刪除:

var vm = new Vue({
    data: {
        a: 1
    }
})
//vm.a是響應式的
//vm.b不是響應式的

對於已經創建的實例,Vue不能動態添加根級別的響應式屬性,但是可以通過Vue.set(obj,key,value)方法向嵌套對象添加響應式屬性。

var vm = new Vue({
    data: {
        userProfile: {
            name: 'Anika'
        }
    }
})

你可以添加一個新age屬性嵌套的userProfile對象:

Vue.set(vm.userProfile, 'age', 27)

還可以使用vm.$set實例方法,它只是全局Vu.set的別名:

vm.$set(vm.userProfile, 'age', 27)

有事可能需要爲已有對象賦予多個新屬性,所以,如果你想添加新的響應式屬性:

vm.userProfile = Object.assign({}, vm.userProfile, {
    age: 27,
    favoriteColor: 'vue green'
})

顯示過濾/排序結果

有時我們想要顯示一個數組的過濾或者排序副本,而不是實際改變原始值,我們可以創建返回過濾或排序數組的計算屬性:

<li v-for="n in evenNubers">{{ n }}</li>

data: {
    number: [1,2,3,4,5]
},
computed: {
    evenNubers:function() {
        return this.number.reverse()
    }
}

在計算屬性不適用的情況下,可以使用method方法。

一段取值範圍的v-for

v-for也可以取整數。在這種情況下,它將重複多次模板。

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

v-for on a <template>

類似於v-if,你也可以利用帶有v-for的<template>渲染多個元素。比如:

<ul>
    <template v-for="item in items">
        <li>{{ item.msg }}</li>
        <li class="divider" role="presentation"></li>
    </template>
</ul>

v-for with v-if

當它們處於同一節點,v-for的優先級比v-if更高,這意味着v-if將分別重複運行於每個v-for循環中。當你想僅有的一些項渲染節點時,這種優先級的機制會十分有用:

<li v-for="todo in todos" v-if="!todo.isComplete">
    {{ todo }}
</li>

一個組件的v-for

在自定義組件裏,你可以像任何普通元素一樣用v-for:

<my-component v-for="item in items" :key="item.id"></my-component>

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

然而,任何數據都不會自動傳遞到組件中,因爲組件有自己的獨立作用域,爲了把迭代數據傳遞到組件裏,我們要用props:

<my-component
    v-for="(item, index) in items"
    :item="item"
    :index="index"
    :key="item.id"
></my-component>

不自動將item注入到原組件裏的原因是這會使得組件與v-for的運作耦合,明確組件數據的來源能夠使組件在其他場合重複使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章