7 способов улучшить циклы Vue v-for

В Vue циклы v-for — это то, что каждый проект будет использовать в тот или иной момент. Они позволяют вам писать циклы for в коде вашего шаблона.

Узнаете больше из видео? Посмотрите мое видео на YouTube на эту же тему.

Это замечательно для таких вещей, как…

  • Отображение массивов или списков
  • Итерация по свойствам объекта

В самом простом случае циклы Vue v-for используются следующим образом.

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

Однако в этой статье мы рассмотрим несколько замечательных способов сделать ваш код v-for более точным, предсказуемым и эффективным.

Хорошо — приступим.

1. Всегда используйте ключи в циклах Vue v-for

Для начала мы обсудим общую передовую практику, которую большинство разработчиков Vue уже знает — используйте :key в своих циклах v-for. Установив уникальный ключевой атрибут, вы гарантируете, что ваш компонент работает так, как вы ожидаете.

Если мы не используем ключи, 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, вы будете перебирать каждый элемент вашего массива независимо от вашего условного выражения.

// BAD CODE! 
<ul> 
  <li 
    v-for='product in products'
    :key='product._id' 
    v-if='product.onSale' 
  > 
    {{ product.name }} 
  </li> 
</ul>

Так в чем проблема?

Допустим, в массиве нашего продукта тысячи товаров, но в продаже есть только 3 продукта, которые мы хотим отобразить.

Каждый раз при повторном рендеринге Vue будет перебирать тысячи товаров, даже если 3 товара в продаже вообще не изменились.

Постарайтесь избежать этого.

Давайте рассмотрим две альтернативы, которые мы можем использовать вместо соединения v-for с v-if.

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 is при решении, отображать ли список вообще.

Например, что, если мы хотим отображать список наших продуктов только тогда, когда пользователь вошел в систему.

<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 ложно, нам вообще не придется повторять.

Потрясающий.

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'>       
      {{ index }} | {{ key }} - {{ item }}     
    </span>   
  </li> 
</ul>

Вывод

Надеюсь, эта короткая статья научила вас некоторым передовым методам использования директивы Vue v-for.

Какие еще советы у вас есть? Дайте знать в ответах!!

Удачного кодирования 🙂

Первоначально опубликовано на https://learnvue.co 25 февраля 2020 г.