Slots — это мощный механизм компонентов во Vue.js,
на базе которого построена библиотека Quasar. Они позволяют создавать
гибкие и переиспользуемые компоненты, отделяя структуру от содержания. В
Quasar слоты активно применяются в таких компонентах, как
QCard, QTable, QDialog и многих
других.
Слот представляет собой место в компоненте, куда можно передавать произвольный контент из родительского компонента. Простое использование слота выглядит следующим образом:
<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 (слоты с областью видимости) — это расширение стандартных слотов. Они позволяют передавать данные из дочернего компонента в родительский, обеспечивая динамическую генерацию содержимого. В 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:
<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 создаёт свою вкладку и
соответствующий слот панели. Такой подход делает интерфейс полностью
динамическим.
scoped slots следует внимательно работать с
props, чтобы избежать ошибок передачи данных.Slots и scoped slots в Quasar — это фундамент для построения сложных компонентов, гибкой кастомизации контента и динамического интерфейса. Их правильное понимание позволяет создавать чистый, модульный и поддерживаемый код.