Таблицы данных v-data-table

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

Синтаксис базовой таблицы:

<v-data-table
  :headers="headers"
  :items="items"
  :items-per-page="5"
>
</v-data-table>
  • headers — массив объектов, описывающих заголовки таблицы (text, value, sortable, align).
  • items — массив объектов с данными для строк.
  • items-per-page — количество элементов на одной странице.

Пример структуры headers:

const headers = [
  { text: 'Имя', value: 'name', sortable: true },
  { text: 'Возраст', value: 'age', sortable: true, align: 'center' },
  { text: 'Город', value: 'city', sortable: false }
];

Настройка сортировки

Сортировка в v-data-table управляется через свойство sort-by и событие update:sort-by. Можно указать начальное поле для сортировки и направление (asc или desc).

<v-data-table
  :headers="headers"
  :items="items"
  sort-by="age"
  :sort-desc="true"
>
</v-data-table>
  • sort-by — поле, по которому выполняется сортировка.
  • sort-desc — направление сортировки (по умолчанию false — по возрастанию).

Для динамической сортировки можно использовать слоты header.<name> и кастомные методы обработки:

<template v-slot:header.age="{ props }">
  <v-btn @click="sortBy('age')">Возраст</v-btn>
</template>

Фильтрация данных

v-data-table поддерживает глобальный фильтр через свойство search и локальные фильтры через вычисляемые свойства Vue.

<v-data-table
  :headers="headers"
  :items="items"
  v-model:search="search"
>
</v-data-table>
data() {
  return {
    search: ''
  }
}

Для сложной фильтрации используется метод custom-filter, позволяющий задать логику фильтрации на основе любого поля:

function customFilter(value, search, item) {
  return item.name.toLowerCase().includes(search.toLowerCase());
}
<v-data-table
  :headers="headers"
  :items="items"
  :custom-filter="customFilter"
  v-model:search="search"
>
</v-data-table>

Пагинация и управление страницами

Компонент имеет встроенную поддержку пагинации через pagination или новые свойства page, items-per-page, total-items.

<v-data-table
  :headers="headers"
  :items="items"
  :items-per-page="10"
  v-model:page="currentPage"
>
</v-data-table>
  • page — текущая страница.
  • items-per-page — количество элементов на странице.
  • total-items — используется для асинхронных данных, чтобы указать общее количество элементов.

Для работы с серверной пагинацией применяется событие update:page и метод загрузки данных с сервера:

watch: {
  currentPage(val) {
    fetchData(val, this.itemsPerPage);
  }
}

Кастомизация ячеек

Для создания сложных ячеек таблицы используется система слотов. Каждый слот привязан к полю в headers.

<v-data-table
  :headers="headers"
  :items="items"
>
  <template v-slot:item.age="{ item }">
    <span :class="{ 'text-success': item.age < 30 }">{{ item.age }}</span>
  </template>
</v-data-table>
  • item.<value> — слот для конкретного поля таблицы.
  • Можно использовать любые Vue-компоненты внутри ячейки.

Добавление действий и чекбоксов

Для добавления чекбоксов используется v-data-table с show-select, что позволяет отмечать строки:

<v-data-table
  :headers="headers"
  :items="items"
  show-select
  item-key="id"
  v-model:selected="selectedItems"
>
</v-data-table>
  • item-key — уникальный идентификатор строки.
  • v-model:selected — массив выбранных элементов.

Для действий, например кнопок редактирования, применяется слот item.actions:

<template v-slot:item.actions="{ item }">
  <v-btn icon @click="editItem(item)">
    <v-icon>mdi-pencil</v-icon>
  </v-btn>
</template>

Интеграция с асинхронными данными

v-data-table поддерживает серверные данные через свойства loading и слоты body.append для отображения индикатора загрузки.

<v-data-table
  :headers="headers"
  :items="items"
  :loading="loading"
>
  <template v-slot:body.append>
    <tr v-if="loading">
      <td :colspan="headers.length">
        Загрузка данных...
      </td>
    </tr>
  </template>
</v-data-table>
  • loading — логическое свойство, показывающее состояние загрузки.
  • Асинхронная загрузка реализуется через методы Vue и watch для page и items-per-page.

Расширенные возможности

  • Группировка строк через group-by и group-desc.
  • Фиксированные заголовки с height и fixed-header.
  • Кастомная сортировка и фильтрация для сложных типов данных.
  • Слоты no-data и no-results для отображения сообщений, когда данных нет или фильтр пуст.

Пример группировки:

<v-data-table
  :headers="headers"
  :items="items"
  group-by="city"
  show-group-by
>
</v-data-table>

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