Итераторы данных v-data-iterator

v-data-iterator является универсальным компонентом Vuetify для организации отображения коллекций данных с поддержкой пагинации, сортировки, фильтрации и кастомного рендеринга элементов. Он не предоставляет готовый визуальный вид, как v-data-table, а фокусируется на логике обработки данных, позволяя создавать собственные структуры отображения.

Ключевые свойства:

  • items — массив объектов, которые будут итерироваться.
  • item-key — имя поля объекта, используемое как уникальный ключ.
  • page и items-per-page — управление пагинацией.
  • sort-by и sort-desc — сортировка данных по выбранному полю и направлению.
  • filter — функция или строка для фильтрации элементов.
  • loading — состояние загрузки данных, отображает индикатор при необходимости.
  • total-items — явное указание общего количества элементов, полезно при серверной пагинации.

Пример базовой структуры:

<v-data-iterator
  :items="users"
  :items-per-page="5"
  item-key="id"
  :sort-by="['name']"
  :sort-desc="[false]"
>
  <template v-slot:default="{ items }">
    <v-card
      v-for="user in items"
      :key="user.id"
      class="mb-2"
    >
      <v-card-title>{{ user.name }}</v-card-title>
      <v-card-text>{{ user.email }}</v-card-text>
    </v-card>
  </template>
</v-data-iterator>

В этом примере v-data-iterator обеспечивает:

  • Отслеживание текущей страницы и количества элементов.
  • Сортировку по имени.
  • Доступ к отфильтрованному и отсортированному массиву items через слот default.

Слоты и кастомизация рендеринга

v-data-iterator предоставляет гибкие слоты для полного контроля отображения:

  1. default — основной слот, получает items, которые нужно отображать.
  2. footer — для кастомного рендеринга панели пагинации.
  3. no-data — отображается при отсутствии элементов.
  4. progress — позволяет вставлять индикатор загрузки при loading.

Пример с кастомной пагинацией:

<v-data-iterator
  :items="users"
  :items-per-page="5"
  item-key="id"
>
  <template v-slot:default="{ items }">
    <v-list>
      <v-list-item v-for="user in items" :key="user.id">
        <v-list-item-content>
          <v-list-item-title>{{ user.name }}</v-list-item-title>
        </v-list-item-content>
      </v-list-item>
    </v-list>
  </template>

  <template v-slot:footer="{ page, itemsPerPage, totalItems, updatePagination }">
    <v-pagination
      v-model="page"
      :length="Math.ceil(totalItems / itemsPerPage)"
      @input="updatePagination(page)"
    />
  </template>
</v-data-iterator>

Слот footer получает методы управления пагинацией (updatePagination) и данные о текущей странице, что позволяет полностью контролировать логику навигации.


Фильтрация и сортировка данных

Фильтрация:

  • Если filter передан как строка, компонент применяет поиск по всем полям элементов.
  • Если filter — функция (item, query) => boolean, возможна сложная логика фильтрации.

Пример функции фильтрации:

filterFunction(item, query) {
  return item.name.toLowerCase().includes(query.toLowerCase()) ||
         item.email.toLowerCase().includes(query.toLowerCase());
}

Использование:

<v-data-iterator
  :items="users"
  :filter="filterFunction"
>
  ...
</v-data-iterator>

Сортировка:

  • sort-by принимает массив полей для сортировки.
  • sort-desc массив булевых значений, определяющих направление сортировки для каждого поля.
  • Поддержка пользовательских функций сортировки через слот custom-sort.

Пример пользовательской сортировки:

<v-data-iterator
  :items="users"
  :sort-by="['age']"
  :sort-desc="[true]"
  :custom-sort="(items, sortBy, sortDesc) => {
    return items.sort((a, b) => sortDesc[0] ? b.age - a.age : a.age - b.age);
  }"
>

Серверная пагинация и асинхронные данные

v-data-iterator поддерживает работу с серверными источниками данных через:

  • Свойство total-items для указания общего числа элементов.
  • Обновление массива items при изменении страницы (page) или количества элементов на странице (items-per-page).
  • Использование loading для отображения индикатора во время запроса.

Пример:

<v-data-iterator
  :items="users"
  :total-items="totalUsers"
  :items-per-page="10"
  :loading="loading"
  item-key="id"
  @update:page="fetchUsers"
  @update:items-per-page="fetchUsers"
>
  <template v-slot:default="{ items }">
    <v-list>
      <v-list-item v-for="user in items" :key="user.id">
        {{ user.name }}
      </v-list-item>
    </v-list>
  </template>
</v-data-iterator>

Метод fetchUsers выполняет запрос на сервер с учетом текущей страницы и размера страницы, после чего обновляет массив users и общее количество totalUsers.


Оптимизация больших наборов данных

  • Использование виртуализации через сторонние компоненты (например, vue-virtual-scroller) позволяет рендерить только видимые элементы.
  • Предварительная сортировка и фильтрация на сервере снижает нагрузку на клиент.
  • Разделение логики пагинации и фильтрации на отдельные функции упрощает поддержку и тестирование.

Практические советы

  • Использовать item-key обязательно для правильного отслеживания элементов при ререндере.
  • Всегда обрабатывать состояние loading для улучшения UX.
  • Слоты позволяют создавать любую кастомную структуру, от карточек до таблиц, без ограничения дизайна.
  • Функции фильтрации и сортировки дают полный контроль над логикой отображения данных.

v-data-iterator сочетает гибкость и мощные возможности управления коллекциями, оставаясь полностью независимым от визуальных шаблонов и позволяя создавать интерфейсы любой сложности с динамическими данными.