В библиотеке 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 при вводе текста и изменении фильтров.
filterMethod для каждой колонки для точного
управления фильтрацией.filterMultiple: true для множественных
выборов.computed массивы с
filter.@filter-change.Такой подход обеспечивает гибкую, удобную и производительную фильтрацию данных в таблицах Naive UI, с возможностью легко масштабировать фильтры под любые бизнес-требования.