用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的運作耦合,明確組件數據的來源能夠使組件在其他場合重復使用。
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>07vue列表渲染</title>
<script src="./vue.js"></script>
<script>
window.onload = function(){
var vm = new Vue({
el:'.box',
data:{
dataList:['a','b','c','d','e','f'],
newObj:{
"name":"lucy",
"age":18
},
objDataList:[
{
"name":"genery",
"age":18
},
{
"name":"bulse",
"age":20
},
{
"name":"naev",
"age":23
}
]
}
})
}
</script>
</head>
<body>
<div class="box">
<ul>
<!-- v-for 列表數據 -->
<li v-for="(item,index) in dataList">{{index}}---{{item}}</li>
<li v-for="item in dataList">{{item}}</li>
<!-- 對象 -->
<li v-for="(value,key) in newObj">{{key}}-------{{value}}</li>
<li v-for="value in newObj">{{value}}</li>
<!-- 字典形式 -->
<li v-for="datadict in objDataList">{{datadict}}</li>
<li v-for="datadict in objDataList">{{datadict.name}}</li>
<li v-for="datadict in objDataList">{{datadict.age}}</li>
</ul>
<div v-for="item in dataList">div: {{item}}</div>
</div>
</body>
</html>
vue的列表渲染其實就是通過指令v-for可以將一組數據渲染到頁面中,這一組數據可以是數組抑或是對象,v-for指令需要使用item in items形式的特殊語法,items是源數據數組并且item是數組元素迭代的別名。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。