Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Списки: v-for и key

Директива v-for повторяет элемент для каждого значения массива. Вместо цикла, который создаёт элементы через createElement, вы описываете один элемент, а Vue выводит столько, сколько записей в данных.

Вывод массива

<!-- src/App.vue -->
<script setup>
import { ref } from 'vue'
 
const todos = ref([
  { id: 1, text: 'Купить хлеб', done: true },
  { id: 2, text: 'Позвонить Анне', done: false },
  { id: 3, text: 'Написать отчёт', done: false },
])
</script>
 
<template>
  <ul>
    <li v-for="todo in todos" :key="todo.id">
      {{ todo.text }}
    </li>
  </ul>
</template>

На странице появится список из трёх задач. Запись todo in todos похожа на for...of: переменная todo по очереди принимает каждую задачу и доступна внутри li.

Атрибут key

:key — уникальный ключ элемента. По нему Vue понимает, какой элемент DOM соответствует какой записи, когда список меняется: при удалении задачи из середины он уберёт ровно её li, а не перерисует все строки. В качестве ключа берите id из данных — строку или число, которые не повторяются.

Индекс

Второй переменной в скобках можно получить номер элемента:

<template>
  <ul>
    <li v-for="(todo, index) in todos" :key="todo.id">
      {{ index + 1 }}. {{ todo.text }}
    </li>
  </ul>
</template>

Строки получат номера: «1. Купить хлеб», «2. Позвонить Анне» и так далее. Нумерация начинается с нуля, поэтому к индексу прибавляется единица.

Изменение списка

Список на странице обновляется, когда меняется массив:

<script setup>
import { ref } from 'vue'
 
const todos = ref([
  { id: 1, text: 'Купить хлеб', done: false },
  { id: 2, text: 'Позвонить Анне', done: false },
])
 
function removeTodo(id) {
  todos.value = todos.value.filter((todo) => todo.id !== id)
}
</script>
 
<template>
  <ul>
    <li v-for="todo in todos" :key="todo.id">
      {{ todo.text }}
      <button @click="removeTodo(todo.id)">Удалить</button>
    </li>
  </ul>
</template>

Кнопка «Удалить» убирает свою задачу: обработчик получает id из текущей итерации цикла.

Другие источники

ЗаписьЧто перебирается
v-for="todo in todos"Элементы массива
v-for="n in 5"Числа от 1 до 5
v-for="(value, key) in user"Значения и ключи объекта

Отфильтрованный список выводят через computed из урока про вычисляемые свойства: v-for="todo in visibleTodos".

Частая ошибка

Ставить v-if и v-for на один элемент:

<li v-for="todo in todos" v-if="!todo.done" :key="todo.id">
  {{ todo.text }}
</li>

v-if выполняется раньше v-for, и переменной todo в нём ещё нет — Vue выдаст ошибку. Отфильтруйте список в computed или перенесите v-for на обёртку template, а v-if оставьте на li.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.