v-for
循環最基本的用法是這樣的:
<ul>
<li v-for='product in products'>
{{ product.name }}
</li>
</ul>
1. 始終在v-for循環中使用key
首先,我們讨論的是大多數Vue開發人員已經知道的常見最佳實踐——在
v-for
循環中使用
:key
。通過設定唯一的鍵屬性,可以確定元件按期望的方式工作。
如果我們不使用
:key
,Vue将使DOM盡可能高效。這可能會導緻
v-for
元素出現亂序或其他不可預測的行為。
如果我們對每個元素都有唯一的鍵引用,那麼就可以更好地預測如何操縱DOM。
<ul>
<li
v-for='product in products'
:key='product._id'
>
{{ product.name }}
</li>
</ul>
2. 在一定範圍内使用v-for循環
雖然大多數時候
v-for
用于循環數組或對象,但也有我們隻想疊代特定次數的情況。
例如,假設我們正在為線上商店建立分頁系統,并且我們隻想每頁顯示10個産品。使用變量來跟蹤目前頁碼,就可以像這樣處理分頁。
<ul>
<li v-for='index in 10' :key='index'>
{{ products[page * 10 + index] }}
</li>
</ul>
3. 避免在循環中使用v-if
一個超常見的錯誤是使用
v-if
來過濾
v-for
循環的資料。
雖然看上去直覺了,但這會導緻一個巨大的性能問題——VueJS将優先
v-for
于
v-if
指令。
這意味着元件将周遊每個元素,然後再檢查
v-if
條件以檢視是否應該呈現。
如果你将
v-if
與
v-for
一起使用,無論條件是什麼,都将周遊數組的每一項。
// 不好的做法!
<ul>
<li
v-for='product in products'
:key='product._id'
v-if='product.onSale'
>
{{ product.name }}
</li>
</ul>
那麼問題是什麼?
假設
products
數組有數千個項,但想要渲染的隻有3個在售産品。
每次重新渲染時,即使出售的3種産品根本沒有改變,Vue也必須周遊這數千個項。
必須盡量避免結合使用
v-if
v-for
的情況。(注:if和for已經在vue3得到了支援,v-if優先級高于v-for了,可以一起使用。)
接下來介紹兩個替代方法。
4. 使用computed屬性或方法
為了避免上述問題,我們應該在模闆中進行疊代之前過濾資料。有兩種非常相似的方法可以做到:
- 使用
屬性computed
- 使用過濾方法
随你選擇,下面讓我們快速介紹這兩個方法。
首先,我們隻需要設定一個
computed
屬性。為了獲得與之前的
v-if
相同的功能,代碼看起來像這樣。
<template>
<ul>
<li v-for="products in productsOnSale" :key="product._id">
{{ product.name }}
</li>
</ul>
</template>
<script>
export default {
data () {
return {
products: []
}
},
computed: {
productsOnSale: function () {
return this.products.filter(product => product.onSale)
}
}
}
</script>
這樣的好處是:
- 資料屬性隻會在依賴項發生變化時重新評估
- 模闆隻周遊在售的産品,而不是每一個産品
使用過濾方法的代碼幾乎相同,但使用方法會改變通路模闆内值的方式。但是,如果我們希望能夠将變量傳遞給過濾過程,那麼就應該選擇方法這條路。
<template>
<ul>
<li v-for="products in productsOnSale(50))" :key="product._id">
{{ product.name }}
</li>
</ul>
</template>
<script>
export default {
data () {
return {
products: []
}
},
methods: {
productsOnSale (maxPrice) {
return this.products.filter(product => product.onSale && product.price < maxPrice)
}
}
}
</script>
5. 或者在循環外包一層元素
在決定是否完全渲染清單時,你可能還是想要将
v-for
v-if
結合起來。
例如,如果我們隻想在使用者登入時呈現産品清單怎麼辦。
錯誤代碼:
<ul>
<li
v-for='product in products'
:key='product._id'
v-if='isLoggedIn' <!-- HERE -->
>
{{ product.name }}
</li>
</ul>
這有什麼問題?
和之前一樣。Vue模闆會優先考慮
v-for
——是以會周遊每個元素并檢查
v-if
。
即使最後什麼都不渲染,也會循環數千個元素。
對于此示例,有一個簡單的解決方案是移動
v-if
語句。
更好的代碼!
<ul v-if='isLoggedIn'> <!-- Much better -->
<li
v-for='product in products'
:key='product._id'
>
{{ product.name }}
</li>
</ul>
這要好得多,因為如果
isLoggedIn
為
false
——那就根本不需要疊代。
6. 通路循環中的索引
除了周遊數組并通路每個元素之外,我們還可以跟蹤每個項目的索引。
為此,我們需要在項目之後添加一個索引值。這樣做超級簡單,但對于分頁、顯示清單索引、顯示排名等都很有用。
<ul>
<li v-for='(products, index) in products' :key='product._id' >
Product #{{ index }}: {{ product.name }}
</li>
</ul>
7. 疊代對象
到目前為止,我們隻研究了使用
v-for
來周遊數組。但是我們也可以很輕松地學會疊代對象的鍵值對。
與通路元素的索引類似,我們需要向循環中添加另一個值。如果我們使用單個參數循環對象,我們将循環所有項。
如果我們添加另一個參數,則将獲得項和鍵。如果我們添加第三個參數,則還可以通路
v-for
循環的索引。
假設我們想周遊産品中的每個屬性。那麼代碼如下:
<ul>
<li v-for='(products, index) in products' :key='product._id' >
<span v-for='(item, key, index) in product' :key='key'>
{{ item }}
</span>
</li>
</ul>
代碼改變了我們,也改變了世界