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

В библиотеке Naive UI фильтрация данных в таблицах реализуется через компонент n-data-table с использованием свойства columns для задания правил фильтрации и свойства data для передачи исходного массива данных. Основной принцип работы заключается в определении функций фильтрации для отдельных колонок или глобальной фильтрации всего набора данных.

Настройка фильтров для колонок

Каждая колонка таблицы в Naive UI может содержать объект фильтров в формате:

const columns = [
  {
    title: 'Имя',
    key: 'name',
    filters: [
      { label: 'Алексей', value: 'Алексей' },
      { label: 'Мария', value: 'Мария' }
    ],
    filterMethod: (value, row) => row.name === value
  },
  {
    title: 'Возраст',
    key: 'age',
    filters: [
      { label: 'До 30', value: 'under30' },
      { label: '30 и старше', value: '30plus' }
    ],
    filterMethod: (value, row) => value === 'under30' ? row.age < 30 : row.age >= 30
  }
]
  • filters — массив объектов с label и value, определяющий доступные опции фильтрации.
  • filterMethod — функция, принимающая значение фильтра и объект строки, возвращает true, если строка удовлетворяет условию фильтрации.

Множественная фильтрация

Naive UI поддерживает одновременное применение нескольких фильтров. Для этого у колонки есть свойство filterMultiple:

{
  title: 'Статус',
  key: 'status',
  filters: [
    { label: 'Активный', value: 'active' },
    { label: 'Неактивный', value: 'inactive' }
  ],
  filterMultiple: true,
  filterMethod: (value, row) => value.includes(row.status)
}

Здесь value — массив выбранных фильтров, и функция filterMethod проверяет, входит ли статус строки в этот массив. Это позволяет пользователю выбирать сразу несколько категорий.

Глобальная фильтрация данных

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

import { reactive, computed } from 'vue'

const state = reactive({
  data: [
    { name: 'Алексей', age: 25, status: 'active' },
    { name: 'Мария', age: 32, status: 'inactive' }
  ],
  searchText: ''
})

const filteredData = computed(() =>
  state.data.filter(item =>
    Object.values(item).some(val =>
      String(val).toLowerCase().includes(state.searchText.toLowerCase())
    )
  )
)

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

Кастомные компоненты фильтров

Для более сложных сценариев Naive UI позволяет использовать пользовательские компоненты внутри фильтров через слот filter:

<n-data-table :columns="columns" :data="data">
  <template #filter-age="{ column, filterValue, updateFilterValue }">
    <n-slider
      v-model:value="filterValue"
      :min="18"
      :max="65"
      @update:value="updateFilterValue"
    />
  </template>
</n-data-table>

С помощью слота filter-age создается интерактивный слайдер для фильтрации по возрасту. Функция updateFilterValue обновляет значение фильтра и автоматически применяет фильтрацию через filterMethod.

Асинхронная фильтрация

Если данные загружаются с сервера, фильтрация может выполняться асинхронно. Для этого используется событие filter-change:

<n-data-table
  :columns="columns"
  :data="data"
  @filter-change="handleFilterChange"
/>

<script>
function handleFilterChange(filters) {
  fetch(`/api/users?filters=${JSON.stringify(filters)}`)
    .then(res => res.json())
    .then(json => {
      data.value = json
    })
}
</script>

filters — объект, где ключи соответствуют колонкам, а значения — выбранным фильтрам. Это позволяет реализовать серверную фильтрацию с динамическим обновлением таблицы.

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

Для больших таблиц следует избегать фильтрации на каждом рендере через computed без debounce. Рекомендуется использовать дебаунс поиска или фильтрации с помощью библиотек вроде lodash:

import { debounce } from 'lodash'

const debouncedFilter = debounce(() => {
  filteredData.value = state.data.filter(/* условие */)
}, 300)

Это снижает нагрузку на UI при вводе текста и изменении фильтров.

Итоговые рекомендации по фильтрации в Naive UI

  • Определять filterMethod для каждой колонки для точного управления фильтрацией.
  • Использовать filterMultiple: true для множественных выборов.
  • Для глобального поиска применять computed массивы с filter.
  • В сложных интерфейсах создавать кастомные фильтры через слоты.
  • Асинхронную фильтрацию реализовывать через @filter-change.
  • Для больших данных применять дебаунс или серверную фильтрацию.

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