Transfer

Компонент Transfer в библиотеке Naive UI предназначен для организации двустороннего переноса элементов между двумя списками. Он широко применяется для управления выборкой элементов из большого набора данных, позволяя пользователю быстро фильтровать и переносить элементы. В Naive UI компонент реализован с учетом реактивности Vue 3 и поддерживает широкий спектр настроек, включая кастомизацию отображения элементов, фильтровку и управление состоянием выбора.

Структура и основные свойства

Компонент Transfer имеет базовую структуру из двух панелей: источник (source) и приемник (target). Каждый элемент списка представляет собой объект с обязательным свойством key и дополнительными свойствами, которые можно использовать для отображения. Основные свойства компонента:

  • v-model:value – массив ключей выбранных элементов в целевой панели.
  • options – массив объектов, представляющих элементы, каждый объект должен содержать как минимум label и value.
  • filterable – включение поиска по списку элементов.
  • titles – массив из двух строк, задающий заголовки для левой и правой панели.
  • target-order – определяет порядок элементов в правой панели: original, push или unshift.

Пример базового использования:

<template>
  <n-transfer
    v-model:value="selectedKeys"
    :options="options"
    filterable
    :titles="['Доступные', 'Выбранные']"
  />
</template>

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

const options = [
  { label: 'Элемент 1', value: 1 },
  { label: 'Элемент 2', value: 2 },
  { label: 'Элемент 3', value: 3 },
]

const selectedKeys = ref([2])
</script>

Кастомизация элементов

Transfer поддерживает слоты для элементов, что позволяет полностью контролировать отображение каждого объекта. Например, можно добавить иконки, описания или цветовые метки для элементов.

<n-transfer
  v-model:value="selectedKeys"
  :options="options"
>
  <template #option="{ option }">
    <div>
      <span style="font-weight: bold">{{ option.label }}</span>
      <span style="color: gray; font-size: 0.85em">{{ option.description }}</span>
    </div>
  </template>
</n-transfer>

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

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

Свойство filterable добавляет текстовое поле поиска. По умолчанию поиск осуществляется по label элемента, но можно настроить функцию фильтрации через filter:

<n-transfer
  v-model:value="selectedKeys"
  :options="options"
  filterable
  :filter="(query, option) => option.label.includes(query) || option.description.includes(query)"
/>

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

Управление порядком элементов

Свойство target-order управляет расположением элементов в правой панели:

  • original – сохраняется порядок из массива options.
  • push – новые элементы добавляются в конец.
  • unshift – новые элементы добавляются в начало.

Пример:

<n-transfer
  v-model:value="selectedKeys"
  :options="options"
  target-order="push"
/>

Обработка событий

Компонент генерирует несколько событий, полезных для взаимодействия с внешними функциями:

  • update:value – вызывается при изменении выбранных элементов.
  • change – срабатывает при перемещении элементов между панелями.
  • scroll – информирует о прокрутке панели.
  • select – событие выбора элемента, возвращает ключ выбранного объекта.
<n-transfer
  v-model:value="selectedKeys"
  :options="options"
  @change="onChange"
  @select="onSelect"
/>

<script setup>
function onChange(newValues) {
  console.log('Перенос элементов:', newValues)
}

function onSelect(selectedKey) {
  console.log('Выбран элемент:', selectedKey)
}
</script>

Поддержка disabled и read-only режимов

Каждый элемент может быть неактивным, если установить свойство disabled. Также сам компонент поддерживает глобальный disabled и readonly режимы для блокировки взаимодействия:

<n-transfer
  v-model:value="selectedKeys"
  :options="options"
  :disabled="true"
/>

Советы по работе с большими массивами

Для больших наборов данных рекомендуется:

  • Использовать виртуализацию списка через virtual-scroll.
  • Фильтровать данные заранее на уровне состояния приложения.
  • Использовать уникальные и короткие key для ускорения реактивной отрисовки.

Интеграция с другими компонентами

Transfer часто комбинируется с Form и Data Table, позволяя выбирать элементы из таблицы и переносить их в выбранный список для дальнейшей обработки. Также возможна интеграция с Vuex или Pinia для хранения состояния выбранных элементов на уровне всего приложения.

Визуальные улучшения

  • render-content позволяет кастомизировать отображение каждого блока.
  • Стили можно контролировать через CSS-переменные или классы n-transfer и n-transfer-panel.
  • Поддержка темы: светлая и темная тема применяются автоматически через Naive UI Theme Provider.

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