Использование slots

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


Простые слоты

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

<template>
  <v-card>
    <slot>Здесь будет контент по умолчанию</slot>
  </v-card>
</template>

Если при использовании компонента не передан контент, отобразится текст из дефолтного слота. Если передан — он заменит стандартное содержимое:

<v-card>
  <p>Пользовательский контент</p>
</v-card>

Именованные слоты

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

<template>
  <v-dialog>
    <template v-slot:activator="{ on, attrs }">
      <v-btn v-bind="attrs" v-on="on">Открыть диалог</v-btn>
    </template>

    <v-card>
      <slot name="header">Заголовок по умолчанию</slot>
      <slot name="body">Тело по умолчанию</slot>
      <slot name="footer">Футер по умолчанию</slot>
    </v-card>
  </v-dialog>
</template>

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

<my-dialog>
  <template v-slot:header>
    <h3>Пользовательский заголовок</h3>
  </template>

  <template v-slot:body>
    <p>Основной текст диалога</p>
  </template>

  <template v-slot:footer>
    <v-btn color="primary">Подтвердить</v-btn>
  </template>
</my-dialog>

Scoped slots

Scoped slots предоставляют доступ к данным дочернего компонента. Это особенно полезно для компонентов типа v-data-table или v-select, где требуется динамическое управление содержимым.

<v-data-table
  :items="users"
  :headers="headers"
>
  <template v-slot:item.name="{ item }">
    <strong>{{ item.name }}</strong>
  </template>

  <template v-slot:item.email="{ item }">
    <em>{{ item.email }}</em>
  </template>
</v-data-table>

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


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

Vuetify позволяет создавать динамические слоты, имя которых задается через переменную. Это особенно удобно для компонентов с множеством повторяющихся элементов, например, в v-tabs или v-carousel.

<v-tabs v-model="tab">
  <v-tab v-for="t in tabs" :key="t">{{ t.label }}</v-tab>

  <v-tab-item v-for="t in tabs" :key="t.name">
    <template v-slot:[`default`]>
      <p>{{ t.content }}</p>
    </template>
  </v-tab-item>
</v-tabs>

С помощью синтаксиса v-slot:[name] можно задавать имена слотов динамически, что повышает гибкость компонентов и уменьшает дублирование кода.


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

Многие компоненты Vuetify уже используют слоты для расширяемости. Например, v-select позволяет полностью кастомизировать каждый элемент списка:

<v-select
  :items="fruits"
  label="Выберите фрукт"
>
  <template v-slot:item="{ item }">
    <v-list-item>
      <v-list-item-content>
        <v-list-item-title>
          ? {{ item.name }}
        </v-list-item-title>
      </v-list-item-content>
    </v-list-item>
  </template>
</v-select>

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


Слоты по умолчанию и fallback

Если в компоненте определены слоты, но пользователь не передает контент, отображается fallback содержимое, которое прописано внутри <slot>.

<slot name="header">Стандартный заголовок</slot>

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


Советы по использованию слотов

  • Использовать именованные слоты для сложных компонентов — это упрощает структуру шаблона и повышает читаемость.
  • Scoped slots применяются для передачи данных из дочернего компонента — ключевой инструмент для кастомизации таблиц, списков и селектов.
  • Fallback контент делает компоненты устойчивыми к отсутствию слотов и обеспечивает корректное отображение по умолчанию.
  • Динамические слоты минимизируют дублирование кода при работе с повторяющимися элементами интерфейса.

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