Slots и scoped slots

Slots — это мощный механизм компонентов во Vue.js, на базе которого построена библиотека Quasar. Они позволяют создавать гибкие и переиспользуемые компоненты, отделяя структуру от содержания. В Quasar слоты активно применяются в таких компонентах, как QCard, QTable, QDialog и многих других.


Основные принципы работы Slots

Слот представляет собой место в компоненте, куда можно передавать произвольный контент из родительского компонента. Простое использование слота выглядит следующим образом:

<q-card>
  <template v-slot:default>
    <p>Контент по умолчанию</p>
  </template>
</q-card>

Здесь default — это стандартный слот, который используется, если не указан конкретный именованный слот. В Quasar большинство компонентов имеют несколько предопределённых слотов, позволяя вставлять контент в нужные области: заголовки, футеры, тела компонентов и т. д.


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

Именованные слоты позволяют управлять размещением контента более детально:

<q-card>
  <template v-slot:header>
    <q-toolbar>
      <q-toolbar-title>Заголовок карточки</q-toolbar-title>
    </q-toolbar>
  </template>

  <template v-slot:default>
    <p>Основное содержание карточки</p>
  </template>

  <template v-slot:footer>
    <q-btn label="Закрыть" color="primary" />
  </template>
</q-card>

Ключевой момент: имена слотов должны совпадать с теми, что предусмотрены компонентом. В противном случае переданный контент не будет отображён.


Scoped slots

Scoped slots (слоты с областью видимости) — это расширение стандартных слотов. Они позволяют передавать данные из дочернего компонента в родительский, обеспечивая динамическую генерацию содержимого. В Quasar это особенно удобно для таблиц, списков и других компонентов с повторяющейся структурой.

Пример использования QTable с scoped slot:

<q-table
  :rows="users"
  :columns="columns"
>
  <template v-slot:body-cell-name="props">
    <q-td :props="props">
      <strong>{{ props.row.name }}</strong>
    </q-td>
  </template>
</q-table>

Здесь props передаёт текущую строку (row) и другую вспомогательную информацию (например, индекс). Scoped slot даёт возможность полностью кастомизировать отображение данных каждой строки.


Деструктуризация props

Для удобства можно сразу деструктурировать объект props:

<template v-slot:body-cell-email="{ row, col }">
  <q-td>
    <a :href="`mailto:${row.email}`">{{ row.email }}</a>
  </q-td>
</template>

В данном примере row и col берутся напрямую из объекта props. Это улучшает читаемость и сокращает код.


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

Quasar поддерживает вложенные слоты, что позволяет создавать сложные структуры интерфейса:

<q-card>
  <template v-slot:header>
    <q-toolbar>
      <q-toolbar-title>Заголовок карточки</q-toolbar-title>
      <template v-slot:action>
        <q-btn icon="edit" />
      </template>
    </q-toolbar>
  </template>
</q-card>

Вложенный слот action внутри q-toolbar обеспечивает возможность добавления кнопок или других элементов прямо в заголовок карточки.


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

С помощью динамических слотов можно генерировать контент на основе данных:

<q-tabs v-model="tab">
  <q-tab
    v-for="item in tabs"
    :key="item.name"
    :name="item.name"
    :label="item.label"
  />
</q-tabs>

<q-tab-panels v-model="tab">
  <q-tab-panel v-for="item in tabs" :key="item.name" :name="item.name">
    <component :is="item.component" />
  </q-tab-panel>
</q-tab-panels>

Здесь каждый элемент массива tabs создаёт свою вкладку и соответствующий слот панели. Такой подход делает интерфейс полностью динамическим.


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

  • Всегда проверять документацию Quasar для конкретного компонента: большинство слотов строго определены.
  • Для scoped slots следует внимательно работать с props, чтобы избежать ошибок передачи данных.
  • Использование слотов повышает переиспользуемость компонентов и уменьшает дублирование кода.
  • Комбинация именованных и scoped slots позволяет создавать гибкие и мощные интерфейсы без потери структуры.

Slots и scoped slots в Quasar — это фундамент для построения сложных компонентов, гибкой кастомизации контента и динамического интерфейса. Их правильное понимание позволяет создавать чистый, модульный и поддерживаемый код.