【轉】用好 Vue 中 v-for 循環的 7 種方法


轉:https://mp.weixin.qq.com/s/wZFsoEEW2-3SvJx3nwPvnw

目錄

  • 1. 始終在 v-for 循環中使用 key

  • 2. 用 v-for 在一個范圍內進行循環

  • 3. 避免在循環中使用 v-if

  • 4. 改用計算屬性或方法

  • 5.  把循環放到包裝元素中

  • 6.  在循環中訪問索引

  • 7. 迭代對象

Vue 中的 v-for 循環允許你在模板代碼中編寫 for 循環,尤其是當我們做下面的操作時非常有用:

  • 渲染數組或列表
  • 遍歷對象屬性

在最基本的用法中,v-for 循環是這樣使用的:

<ul>
  <li v-for='product in products'>
    {{ product.name }}
  </li>
</ul>

不過它還有一些你不知道的用法,可以使你的 v-for 代碼更加精確、和高效。

1. 始終在 v-for 循環中使用 key

首先要討論的很多人都已經知道的一種用法:在 v-for 循環中使用 key。通過設置唯一的 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 個商品品。通過使用變量來跟蹤我們當前的頁碼,可以像這樣處理分頁:

looping over a range<ul>
  <li v-for='index in 10' :key='index'>
    {{ products[page * 10 + index] }}
  </li>
</ul>

3. 避免在循環中使用 v-if

在 v-for 循環中錯誤地使用 v-if 來過濾數據[1] 是非常常見的。

雖然這樣做看起來很直觀,但它會導致一個巨大的性能問題—— vue 的 v-for 優先於 v-if 指令 [2]

這意味着你的組件會遍歷每一個元素,然后檢查 v-if 條件查看它是否應該被渲染。

如果把 v-if 與 v-for 放在一起使用,無論你的條件是什么,都會將遍歷數組的每一個元素。

// 不好的代碼
<ul>
  <li 
    v-for='product in products' 
    :key='product._id' 
    v-if='product.onSale'
  >

    {{ product.name }}
  </li>
</ul>

上面的代碼會引發什么題呢?

假如我們的商品數組中有幾千個項目,但是只有 3 個處於銷售狀態產品需要渲染。那么每次重新渲染時,即使銷售的 3 種產品根本沒有變化,vue 也必須遍歷幾千個項目。所以應該盡量避免這種情況。

接下來是兩種替代方案,而不是把 v-for 與 v-if 放在一起用。

插播廣告:推薦一個有意思的公眾號圖片

 

點擊查看:寫給 js 程序員的 Dart 語言教程

4. 改用計算屬性或方法

為了避免上述問題,應該在我們的模板中迭代之前先過濾這些數據。有兩種非常相似的方法可以做到:

  1. 使用計算屬性
  2. 使用過濾方法

至於用哪種方法你自己說了算。下面對兩者進行簡單的介紹。

首先需要設置一個計算屬性。為了打到與之前使用 v-if 相同的效果,代碼應該是這樣:

<ul>
  <li v-for='products in productsOnSale' :key='product._id' >
    {{ product.name }}
  </li>

</ul>

/
/ ...
<script>
  export default {
    data () {
      return {
        products: []
      }
    },
    computed: {
      productsOnSale: function () {
        return this.products.filter(product => product.onSale)
      }
    }
  }
</
script>

這樣做有幾個好處:

  1. 數據屬性只會在依賴項發生變化時才會被重新評估
  2. 模板只會遍歷在售商品,而不是每一個項目

第二種方法的代碼幾乎和前面一樣:

<ul>
  <li v-for='products in productsOnSale(50))' :key='product._id' >
    {{ product.name }}
  </li>

</ul>

/
/ ...

<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 遍歷數組。但是我們可以很容易地迭代對象的鍵值對。

與訪問元素的索引類似,我們必須向循環中添加另一個值。如果用單個參數循環對象的話將會循環所有項目。

如果我們再添加一個參數,將會得到 item 和 key。如果添加第三個還可以訪問 v-for 循環的 index

假設要遍歷商品的每個屬性,代碼應該是這樣:

<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>

Reference

[1]

過濾數據:https://learnvue.co/2020/01/how-to-use-vuejs-filters-to-write-better-code/

[2]

vue 的 v-for 優先於 v-if 指令 :https://vuejs.org/v2/style-guide/#Avoid-v-if-with-v-for-essential

目錄

  • 1. 始終在 v-for 循環中使用 key

  • 2. 用 v-for 在一個范圍內進行循環

  • 3. 避免在循環中使用 v-if

  • 4. 改用計算屬性或方法

  • 5.  把循環放到包裝元素中

  • 6.  在循環中訪問索引

  • 7. 迭代對象

Vue 中的 v-for 循環允許你在模板代碼中編寫 for 循環,尤其是當我們做下面的操作時非常有用:

  • 渲染數組或列表
  • 遍歷對象屬性

在最基本的用法中,v-for 循環是這樣使用的:

<ul>
  <li v-for='product in products'>
    {{ product.name }}
  </li>
</ul>

不過它還有一些你不知道的用法,可以使你的 v-for 代碼更加精確、和高效。

1. 始終在 v-for 循環中使用 key

首先要討論的很多人都已經知道的一種用法:在 v-for 循環中使用 key。通過設置唯一的 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 個商品品。通過使用變量來跟蹤我們當前的頁碼,可以像這樣處理分頁:

looping over a range<ul>
  <li v-for='index in 10' :key='index'>
    {{ products[page * 10 + index] }}
  </li>
</ul>

3. 避免在循環中使用 v-if

在 v-for 循環中錯誤地使用 v-if 來過濾數據[1] 是非常常見的。

雖然這樣做看起來很直觀,但它會導致一個巨大的性能問題—— vue 的 v-for 優先於 v-if 指令 [2]

這意味着你的組件會遍歷每一個元素,然后檢查 v-if 條件查看它是否應該被渲染。

如果把 v-if 與 v-for 放在一起使用,無論你的條件是什么,都會將遍歷數組的每一個元素。

// 不好的代碼
<ul>
  <li 
    v-for='product in products' 
    :key='product._id' 
    v-if='product.onSale'
  >

    {{ product.name }}
  </li>
</ul>

上面的代碼會引發什么題呢?

假如我們的商品數組中有幾千個項目,但是只有 3 個處於銷售狀態產品需要渲染。那么每次重新渲染時,即使銷售的 3 種產品根本沒有變化,vue 也必須遍歷幾千個項目。所以應該盡量避免這種情況。

接下來是兩種替代方案,而不是把 v-for 與 v-if 放在一起用。

插播廣告:推薦一個有意思的公眾號圖片

 

點擊查看:寫給 js 程序員的 Dart 語言教程

4. 改用計算屬性或方法

為了避免上述問題,應該在我們的模板中迭代之前先過濾這些數據。有兩種非常相似的方法可以做到:

  1. 使用計算屬性
  2. 使用過濾方法

至於用哪種方法你自己說了算。下面對兩者進行簡單的介紹。

首先需要設置一個計算屬性。為了打到與之前使用 v-if 相同的效果,代碼應該是這樣:

<ul>
  <li v-for='products in productsOnSale' :key='product._id' >
    {{ product.name }}
  </li>

</ul>

/
/ ...
<script>
  export default {
    data () {
      return {
        products: []
      }
    },
    computed: {
      productsOnSale: function () {
        return this.products.filter(product => product.onSale)
      }
    }
  }
</
script>

這樣做有幾個好處:

  1. 數據屬性只會在依賴項發生變化時才會被重新評估
  2. 模板只會遍歷在售商品,而不是每一個項目

第二種方法的代碼幾乎和前面一樣:

<ul>
  <li v-for='products in productsOnSale(50))' :key='product._id' >
    {{ product.name }}
  </li>

</ul>

/
/ ...

<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 遍歷數組。但是我們可以很容易地迭代對象的鍵值對。

與訪問元素的索引類似,我們必須向循環中添加另一個值。如果用單個參數循環對象的話將會循環所有項目。

如果我們再添加一個參數,將會得到 item 和 key。如果添加第三個還可以訪問 v-for 循環的 index

假設要遍歷商品的每個屬性,代碼應該是這樣:

<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>

Reference

 

過濾數據:https://learnvue.co/2020/01/how-to-use-vuejs-filters-to-write-better-code/

 

vue 的 v-for 優先於 v-if 指令 :https://vuejs.org/v2/style-guide/#Avoid-v-if-with-v-for-essential


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM