Фильтрация в таблицах

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

Атрибут search и базовая фильтрация

Наиболее простой способ реализовать фильтрацию — использовать проп :search у компонента v-data-table:

<v-data-table
  :headers="headers"
  :items="items"
  :search="searchText"
>
</v-data-table>

<v-text-field
  v-model="searchText"
  label="Поиск"
></v-text-field>
  • headers — массив объектов с описанием колонок (text, value и другие параметры).
  • items — массив данных, который будет отображаться в таблице.
  • searchText — строка, по которой выполняется поиск по всем колонкам таблицы.

Особенности работы search:

  • Поиск регистронезависимый.
  • Выполняется по всем колонкам, кроме тех, которые помечены как filterable: false.

Кастомная фильтрация через слот custom-filter

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

<v-data-table
  :headers="headers"
  :items="items"
  :custom-filter="myFilter"
>
</v-data-table>

<script>
export default {
  methods: {
    myFilter(value, search, item) {
      if (!search) return true;
      return item.name.toLowerCase().includes(search.toLowerCase()) ||
             item.email.toLowerCase().includes(search.toLowerCase());
    }
  }
}
</script>
  • value — значение ячейки.
  • search — строка поиска.
  • item — объект текущей строки.

Такой подход позволяет фильтровать таблицу по нескольким полям одновременно или использовать сложные условия (например, диапазоны чисел, даты или комбинированные фильтры).

Фильтры по колонкам

Vuetify поддерживает фильтрацию конкретных колонок через слоты и использование отдельных v-text-field или v-select для каждого столбца:

<v-data-table
  :headers="headers"
  :items="items"
>
  <template v-slot:top>
    <v-text-field
      v-model="filters.name"
      label="Фильтр по имени"
    ></v-text-field>
    <v-select
      v-model="filters.status"
      :items="statusOptions"
      label="Фильтр по статусу"
    ></v-select>
  </template>
</v-data-table>

<script>
export default {
  data() {
    return {
      filters: {
        name: '',
        status: null
      },
      statusOptions: ['Активен', 'Неактивен']
    };
  },
  computed: {
    filteredItems() {
      return this.items.filter(item => {
        return (!this.filters.name || item.name.includes(this.filters.name)) &&
               (!this.filters.status || item.status === this.filters.status);
      });
    }
  }
}
</script>

Использование вычисляемого свойства filteredItems позволяет легко комбинировать несколько фильтров и передавать результат в таблицу вместо исходного массива items.

Фильтрация с диапазонами и типами данных

Для числовых значений и дат применяются диапазонные фильтры:

<v-data-table
  :headers="headers"
  :items="items"
>
  <template v-slot:top>
    <v-text-field
      v-model.number="filters.minAge"
      label="Минимальный возраст"
      type="number"
    ></v-text-field>
    <v-text-field
      v-model.number="filters.maxAge"
      label="Максимальный возраст"
      type="number"
    ></v-text-field>
  </template>
</v-data-table>

<script>
export default {
  data() {
    return {
      filters: {
        minAge: null,
        maxAge: null
      }
    };
  },
  computed: {
    filteredItems() {
      return this.items.filter(item => {
        return (!this.filters.minAge || item.age >= this.filters.minAge) &&
               (!this.filters.maxAge || item.age <= this.filters.maxAge);
      });
    }
  }
}
</script>

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

Сложные фильтры с использованием комбинированных условий

Можно объединять текстовые, числовые и селект-фильтры в одном вычисляемом свойстве, создавая полноценный динамический фильтр:

computed: {
  filteredItems() {
    return this.items.filter(item => {
      const matchesName = !this.filters.name || item.name.toLowerCase().includes(this.filters.name.toLowerCase());
      const matchesStatus = !this.filters.status || item.status === this.filters.status;
      const matchesAge = (!this.filters.minAge || item.age >= this.filters.minAge) &&
                         (!this.filters.maxAge || item.age <= this.filters.maxAge);
      return matchesName && matchesStatus && matchesAge;
    });
  }
}

Такой подход позволяет комбинировать разные типы фильтров без необходимости писать отдельные методы для каждой колонки.

Оптимизация производительности

  • Для больших массивов данных рекомендуется использовать виртуальные таблицы или серверную фильтрацию, чтобы не перегружать фронтенд.
  • Если фильтрация выполняется часто, стоит кэшировать результаты и минимизировать пересчёты в computed.
  • Использование debounce на текстовые поля уменьшает количество вызовов фильтра при вводе пользователя.

Итоговые возможности

Vuetify предоставляет гибкий набор инструментов для фильтрации таблиц:

  • Простейшая глобальная фильтрация через search.
  • Кастомная фильтрация с custom-filter.
  • Фильтры по отдельным колонкам с вычисляемыми свойствами.
  • Поддержка диапазонов чисел и дат.
  • Комбинирование нескольких фильтров для сложных условий.

Эти возможности делают v-data-table не только визуально удобным, но и функционально мощным инструментом для обработки и отображения данных.