Фильтры и поиск

Naive UI предоставляет мощный набор компонентов для построения пользовательских интерфейсов с фильтрацией и поиском данных. Основной принцип заключается в сочетании компонентов ввода (n-input, n-select, n-radio-group) с реактивными состояниями Vue и отображением данных через n-data-table или списки.


Фильтры с использованием n-select и реактивных данных

Для реализации фильтров часто используют n-select. Пример фильтра по категории:

<template>
  <n-select
    v-model:value="selectedCategory"
    :options="categories"
    placeholder="Выберите категорию"
    clearable
  />
  <n-data-table :columns="columns" :data="filteredData" />
</template>

<script setup>
import { ref, computed } from 'vue'

const data = ref([
  { id: 1, name: 'Товар 1', category: 'A' },
  { id: 2, name: 'Товар 2', category: 'B' },
  { id: 3, name: 'Товар 3', category: 'A' },
])

const categories = [
  { label: 'Категория A', value: 'A' },
  { label: 'Категория B', value: 'B' },
]

const selectedCategory = ref(null)

const filteredData = computed(() => {
  if (!selectedCategory.value) return data.value
  return data.value.filter(item => item.category === selectedCategory.value)
})

const columns = [
  { title: 'ID', key: 'id' },
  { title: 'Название', key: 'name' },
  { title: 'Категория', key: 'category' },
]
</script>

Ключевые моменты:

  • v-model:value обеспечивает двустороннюю привязку значения фильтра.
  • computed позволяет динамически изменять отображаемые данные без ручного обновления таблицы.
  • clearable добавляет возможность сброса фильтра.

Текстовый поиск с n-input

Поиск по текстовым данным реализуется с помощью n-input и реактивного фильтра:

<template>
  <n-input
    v-model:value="searchQuery"
    placeholder="Поиск по названию"
    clearable
  />
  <n-data-table :columns="columns" :data="searchedData" />
</template>

<script setup>
import { ref, computed } from 'vue'

const searchQuery = ref('')

const searchedData = computed(() => {
  if (!searchQuery.value) return data.value
  return data.value.filter(item =>
    item.name.toLowerCase().includes(searchQuery.value.toLowerCase())
  )
})
</script>

Особенности:

  • Приведение к нижнему регистру позволяет реализовать нечувствительный к регистру поиск.
  • Использование computed гарантирует, что таблица автоматически обновляется при изменении запроса.

Сочетание нескольких фильтров

Naive UI позволяет комбинировать фильтры, объединяя несколько условий в одном computed:

const combinedFilter = computed(() => {
  return data.value.filter(item => {
    const matchesCategory = selectedCategory.value
      ? item.category === selectedCategory.value
      : true
    const matchesSearch = searchQuery.value
      ? item.name.toLowerCase().includes(searchQuery.value.toLowerCase())
      : true
    return matchesCategory && matchesSearch
  })
})

Вывод:

  • Фильтрация строится на логическом объединении условий.
  • Каждое условие проверяется отдельно, что упрощает добавление новых фильтров.

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

Для работы с временными фильтрами используют n-date-picker:

<template>
  <n-date-picker
    v-model:value="dateRange"
    type="daterange"
    placeholder="Выберите диапазон дат"
  />
  <n-data-table :columns="columns" :data="dateFilteredData" />
</template>

<script setup>
import { ref, computed } from 'vue'

const dateRange = ref([])

const dateFilteredData = computed(() => {
  if (dateRange.value.length !== 2) return data.value
  const [start, end] = dateRange.value
  return data.value.filter(item => {
    const itemDate = new Date(item.date)
    return itemDate >= start && itemDate <= end
  })
})
</script>

Примечания:

  • type="daterange" позволяет выбирать диапазон дат сразу.
  • Проверка массива dateRange.value.length предотвращает ошибки при незаполненном диапазоне.

Асинхронные фильтры и запросы на сервер

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

import { ref, watch } from 'vue'
import axios from 'axios'

const selectedCategory = ref(null)
const searchQuery = ref('')
const tableData = ref([])

const fetchData = async () => {
  const response = await axios.get('/api/items', {
    params: {
      category: selectedCategory.value,
      search: searchQuery.value
    }
  })
  tableData.value = response.data
}

watch([selectedCategory, searchQuery], fetchData, { immediate: true })

Особенности:

  • watch позволяет отслеживать изменения фильтров и автоматически обновлять данные.
  • Передача фильтров в params упрощает интеграцию с REST API.

Кастомизация внешнего вида фильтров

Naive UI предоставляет пропсы для настройки компонентов:

  • size – размер компонента (small, medium, large)
  • placeholder – текст-заполнитель
  • clearable – кнопка очистки
  • disabled – блокировка выбора

Пример для комбинированного фильтра:

<n-input
  v-model:value="searchQuery"
  size="small"
  placeholder="Поиск..."
  clearable
/>
<n-select
  v-model:value="selectedCategory"
  :options="categories"
  size="small"
  placeholder="Категория"
  clearable
/>

Резюме функционала фильтров и поиска

  • Реактивные состояния Vue (ref, computed) позволяют управлять фильтрацией данных динамически.
  • n-select и n-input подходят для текстовых и категориальных фильтров.
  • Комбинированные фильтры реализуются через объединение условий в computed.
  • Диапазоны дат удобно реализовать с n-date-picker.
  • Асинхронная фильтрация с сервером использует watch и передачу параметров через API.
  • Настройка внешнего вида компонентов позволяет создавать удобный и интуитивный интерфейс фильтров.

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