Slots документация

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

Основы использования слотов

Слоты объявляются в шаблоне компонента через атрибут v-slot (или синтаксис # для краткости). Каждый слот имеет имя, которое определяет, куда будет вставлен контент. Если слот неименованный, он становится default slot.

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

<n-button>
  Нажми меня
</n-button>

Здесь строка "Нажми меня" передается в default слот компонента n-button.

Для именованных слотов синтаксис выглядит так:

<n-card>
  <template #header>
    Заголовок карточки
  </template>
  <template #footer>
    Нижняя часть карточки
  </template>
</n-card>

В этом примере компонент n-card имеет два слота: header и footer. Контент каждого шаблона вставляется в соответствующую область компонента.

Scoped slots

Scoped slots позволяют передавать функции или данные из дочернего компонента в слот, что обеспечивает динамическую генерацию контента.

Пример:

<n-data-table :columns="columns" :data="tableData">
  <template #cell="{ row, column }">
    <span v-if="column.key === 'status'">{{ row.status }}</span>
    <span v-else>{{ row[column.key] }}</span>
  </template>
</n-data-table>
  • cell — именованный слот компонента n-data-table.
  • { row, column } — объект, передаваемый из компонента, содержащий данные строки и колонки.
  • Использование v-if и v-else позволяет гибко управлять отображением данных для разных типов колонок.

Динамические слоты

Naive UI поддерживает динамическое управление слотами через объект, где ключи — это имена слотов, а значения — функции, возвращающие JSX или шаблон.

Пример на JSX:

<n-dropdown
  v-slots={{
    trigger: () => <button>Открыть меню</button>,
    default: () => <n-menu options={menuOptions} />
  }}
/>

Такой подход особенно полезен для создания компонентов с множественными слотами без необходимости писать отдельные <template> блоки.

Вложенные слоты

Компоненты Naive UI часто используют вложенные слоты для сложной кастомизации. Вложенные слоты позволяют комбинировать разные уровни контента.

Пример:

<n-popover>
  <template #trigger>
    <n-button>Показать подсказку</n-button>
  </template>
  <template #default>
    <n-card>
      <template #header>
        Заголовок подсказки
      </template>
      Содержимое подсказки
    </n-card>
  </template>
</n-popover>

Здесь компонент n-popover использует слот trigger для кнопки и слот default для карточки с дополнительными слотами внутри.

Передача функций через слоты

Слоты могут передавать callback-функции для обработки событий. Это позволяет создавать интерактивные интерфейсы без изменения внутренней логики компонента.

Пример:

<n-upload :on-change="handleUpload">
  <template #trigger="{ upload }">
    <n-button @click="upload">Загрузить файл</n-button>
  </template>
</n-upload>
  • trigger получает функцию upload через scoped slot.
  • Вызов upload() инициирует процесс загрузки.

Важные особенности

  1. Совместимость с TypeScript — Naive UI полностью поддерживает типизацию слотов, что позволяет избегать ошибок при передаче данных.
  2. Fallback content — если слот не передан, компонент может отображать содержимое по умолчанию.
  3. Композиция слотов — слоты можно комбинировать и использовать в разных комбинациях, создавая гибкие пользовательские интерфейсы.

Практические советы

  • Для повторного использования сложных шаблонов рекомендуется использовать именованные слоты с scoped параметрами.
  • В сложных компонентах удобно использовать динамические слоты через объект v-slots вместо большого количества вложенных <template>.
  • При работе с формами и таблицами scoped slots позволяют полностью контролировать рендеринг каждого элемента, сохраняя реактивность данных.

Slots в Naive UI предоставляют полноценный инструмент кастомизации, позволяющий строить гибкие и масштабируемые интерфейсы без вмешательства в исходный код компонентов. Использование default, именованных и scoped слотов обеспечивает удобную организацию контента и расширяемость компонентов.