Множественный выбор — один из распространённых интерфейсных паттернов, позволяющий пользователю выбрать несколько значений из набора вариантов. В библиотеке Naive UI для реализации подобного поведения используется несколько компонентов, каждый из которых подходит для разных сценариев:
NSelect с режимом multipleNCheckboxGroupNTransferNTreeSelect с множественным выборомNDropdown с множественным состоянием элементовОсновное различие между ними заключается в способе представления данных, сложности структуры вариантов и удобстве взаимодействия при большом количестве элементов.
Компонент 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>
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.
<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>
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.
<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' }
]
}
]
При работе с деревом важно определить поведение выбора родительских и дочерних элементов.
Выбираются все отмеченные узлы.
Возвращаются только дочерние элементы.
Возвращаются родительские элементы.
Пример:
<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)
})
Это позволяет:
При работе с сотнями или тысячами элементов важно учитывать производительность.
Использование виртуализации
Некоторые компоненты автоматически используют виртуальный скролл.
Ленивая загрузка
<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 | быстрые фильтры в меню |
Правильный выбор компонента зависит от: