Множественный выбор

Множественный выбор — один из распространённых интерфейсных паттернов, позволяющий пользователю выбрать несколько значений из набора вариантов. В библиотеке Naive UI для реализации подобного поведения используется несколько компонентов, каждый из которых подходит для разных сценариев:

  • NSelect с режимом multiple
  • NCheckboxGroup
  • NTransfer
  • NTreeSelect с множественным выбором
  • NDropdown с множественным состоянием элементов

Основное различие между ними заключается в способе представления данных, сложности структуры вариантов и удобстве взаимодействия при большом количестве элементов.


Множественный выбор с помощью NSelect

Компонент NSelect поддерживает режим множественного выбора через свойство multiple. В этом режиме пользователь может выбрать несколько значений, которые отображаются внутри поля ввода в виде тегов.

Базовое использование

<template>
  <n-select
    v-model:value="value"
    multiple
    :options="options"
    placeholder="Выберите значения"
  />
</template>

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

const value = ref([])

const options = [
  { label: 'JavaScript', value: 'js' },
  { label: 'TypeScript', value: 'ts' },
  { label: 'Python', value: 'py' },
  { label: 'Go', value: 'go' }
]
</script>

Особенности режима multiple

  • значение v-model:value всегда является массивом
  • каждый выбранный элемент отображается в виде тега
  • элементы можно удалять по отдельности
  • поддерживается поиск

Пример значения:

['js', 'ts']

Ограничение количества выбранных элементов

Иногда необходимо ограничить максимальное количество вариантов.

<n-select
  v-model:value="value"
  multiple
  :max-tag-count="3"
  :options="options"
/>

Параметры

Свойство Назначение
max-tag-count ограничивает количество отображаемых тегов
max максимальное количество выбранных элементов

Пример ограничения:

<n-select
  v-model:value="value"
  multiple
  :max="5"
  :options="options"
/>

Отображение выбранных элементов

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

Ограничение отображаемых тегов

<n-select
  v-model:value="value"
  multiple
  :max-tag-count="2"
  :options="options"
/>

После превышения лимита оставшиеся элементы отображаются в виде счётчика:

JavaScript | TypeScript | +3

Очистка выбранных значений

Компонент поддерживает быстрое удаление всех выбранных элементов.

<n-select
  v-model:value="value"
  multiple
  clearable
  :options="options"
/>

Кнопка очистки появляется при наличии выбранных значений.


Фильтрация и поиск

При большом количестве вариантов используется встроенный поиск.

<n-select
  v-model:value="value"
  multiple
  filterable
  :options="options"
/>

Пользовательская фильтрация

<n-select
  v-model:value="value"
  multiple
  filterable
  :options="options"
  :filter="filter"
/>
function filter(pattern, option) {
  return option.label.toLowerCase().includes(pattern.toLowerCase())
}

Группы чекбоксов (NCheckboxGroup)

Если варианты должны отображаться сразу на странице без выпадающего меню, используется NCheckboxGroup.

Базовый пример

<template>
  <n-checkbox-group v-model:value="value">
    <n-checkbox value="js">JavaScript</n-checkbox>
    <n-checkbox value="ts">TypeScript</n-checkbox>
    <n-checkbox value="py">Python</n-checkbox>
  </n-checkbox-group>
</template>

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

const value = ref([])
</script>

Поведение

  • v-model:value — массив выбранных значений
  • каждый NCheckbox управляется группой
  • изменение состояния автоматически обновляет массив

Пример значения:

['js', 'py']

Использование списка вариантов

Часто данные поступают динамически. В таком случае используется генерация элементов.

<n-checkbox-group v-model:value="value">
  <n-checkbox
    v-for="item in options"
    :key="item.value"
    :value="item.value"
  >
    {{ item.label }}
  </n-checkbox>
</n-checkbox-group>

Вертикальная и горизонтальная компоновка

Для управления расположением элементов применяется CSS или вспомогательные компоненты.

Пример с NSpace:

<n-checkbox-group v-model:value="value">
  <n-space vertical>
    <n-checkbox value="js">JavaScript</n-checkbox>
    <n-checkbox value="ts">TypeScript</n-checkbox>
    <n-checkbox value="py">Python</n-checkbox>
  </n-space>
</n-checkbox-group>

Компонент Transfer

NTransfer предназначен для работы с большим количеством элементов, где необходимо переносить выбранные значения между двумя списками.

Типичный пример — выбор пользователей, ролей или разрешений.

Базовый пример

<template>
  <n-transfer
    v-model:value="value"
    :options="options"
  />
</template>

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

const value = ref([])

const options = [
  { label: 'Пользователь 1', value: 1 },
  { label: 'Пользователь 2', value: 2 },
  { label: 'Пользователь 3', value: 3 }
]
</script>

Принцип работы

Компонент состоит из двух колонок:

Колонка Назначение
левая доступные элементы
правая выбранные элементы

Перемещение осуществляется с помощью кнопок или двойного клика.


Поиск внутри списков

<n-transfer
  v-model:value="value"
  :options="options"
  filterable
/>

Добавляется поле поиска, упрощающее работу с длинными списками.


Древовидный множественный выбор (NTreeSelect)

Если данные имеют иерархическую структуру, применяется NTreeSelect.

Базовый пример

<n-tree-select
  v-model:value="value"
  multiple
  :options="options"
/>

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

const options = [
  {
    label: 'Frontend',
    key: 'frontend',
    children: [
      { label: 'Vue', key: 'vue' },
      { label: 'React', key: 'react' }
    ]
  },
  {
    label: 'Backend',
    key: 'backend',
    children: [
      { label: 'Node.js', key: 'node' },
      { label: 'Python', key: 'python' }
    ]
  }
]

Связанный выбор (check strategy)

При работе с деревом важно определить поведение выбора родительских и дочерних элементов.

ALL

Выбираются все отмеченные узлы.

CHILD

Возвращаются только дочерние элементы.

PARENT

Возвращаются родительские элементы.

Пример:

<n-tree-select
  v-model:value="value"
  multiple
  checkable
  check-strategy="child"
  :options="options"
/>

Выпадающее меню с множественным состоянием

Иногда множественный выбор реализуется внутри NDropdown, где элементы можно отмечать.

Пример

<n-dropdown
  trigger="click"
  :options="options"
  @select="handleSelect"
/>
const selected = ref([])

function handleSelect(key) {
  if (selected.value.includes(key)) {
    selected.value = selected.value.filter(v => v !== key)
  } else {
    selected.value.push(key)
  }
}

Подобный подход применяется в меню фильтрации таблиц.


Управление состоянием выбранных значений

Во всех компонентах множественного выбора используется единая концепция управления состоянием — массив выбранных значений.

Пример общего состояния:

const selectedValues = ref([])

Добавление элемента:

selectedValues.value.push('js')

Удаление:

selectedValues.value = selectedValues.value.filter(v => v !== 'js')

Проверка наличия:

selectedValues.value.includes('js')

Реактивность и синхронизация

Компоненты Naive UI полностью интегрированы с реактивной системой Vue.

Пример отслеживания изменений:

watch(value, (newValue) => {
  console.log('Выбранные значения:', newValue)
})

Это позволяет:

  • обновлять состояние приложения
  • синхронизировать фильтры
  • отправлять данные на сервер
  • изменять UI

Производительность при большом количестве вариантов

При работе с сотнями или тысячами элементов важно учитывать производительность.

Основные рекомендации

Использование виртуализации

Некоторые компоненты автоматически используют виртуальный скролл.

Ленивая загрузка

<n-tree-select
  :options="options"
  :on-load="loadChildren"
/>

Фильтрация на сервере

При огромных наборах данных поиск выполняется через API.


Стилизация элементов множественного выбора

Naive UI позволяет изменять внешний вид через CSS-переменные.

Пример:

.n-select {
  --n-tag-color: #f0f0f0;
  --n-tag-text-color: #333;
}

Для чекбоксов:

.n-checkbox {
  margin-bottom: 8px;
}

Практические сценарии применения

Множественный выбор широко используется в интерфейсах:

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

  • категории товаров
  • теги статей
  • типы контента

Управление правами доступа

  • роли пользователей
  • разрешения

Конфигурация настроек

  • активные модули
  • доступные функции

Выбор ресурсов

  • пользователи
  • команды
  • проекты

Сравнение компонентов множественного выбора

Компонент Сценарий
NSelect компактный выбор из списка
NCheckboxGroup небольшое количество вариантов
NTransfer работа с длинными списками
NTreeSelect иерархические данные
NDropdown быстрые фильтры в меню

Правильный выбор компонента зависит от:

  • количества вариантов
  • структуры данных
  • сложности интерфейса
  • частоты использования элемента в UI.