Композиция с Quasar компонентами

Quasar Framework предоставляет мощный набор UI-компонентов для создания современных веб-приложений на Vue.js. Одним из ключевых аспектов работы с Quasar является композиция компонентов, которая позволяет строить сложные интерфейсы из простых, переиспользуемых элементов.


Структура Quasar компонента

Каждый Quasar компонент строится по стандартной структуре Vue-компонента:

<template>
  <q-card>
    <q-card-section>
      <div class="text-h6">Заголовок карточки</div>
      <div>Описание содержимого</div>
    </q-card-section>
    <q-card-actions align="right">
      <q-btn label="Действие" color="primary"/>
    </q-card-actions>
  </q-card>
</template>

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

<style scoped>
</style>

Ключевые моменты:

  • template определяет визуальное представление.
  • script setup используется для реактивных данных и логики.
  • style scoped позволяет изолировать стили для компонента.

Quasar поставляется с готовыми компонентами, такими как QLayout, QHeader, QFooter, QDrawer, QPage, которые удобно комбинировать для построения полноценного макета приложения.


Использование QLayout для построения интерфейса

QLayout является основным контейнером для страниц. Его гибкость позволяет создавать как простые, так и сложные структуры с боковыми панелями и верхними шапками.

Пример базового макета:

<q-layout view="hHh lpR fFf">
  <q-header elevated>
    <q-toolbar>
      <q-toolbar-title>Приложение</q-toolbar-title>
    </q-toolbar>
  </q-header>

  <q-drawer show-if-above v-model="drawerOpen">
    <q-list>
      <q-item clickable v-ripple>
        <q-item-section>Пункт меню 1</q-item-section>
      </q-item>
      <q-item clickable v-ripple>
        <q-item-section>Пункт меню 2</q-item-section>
      </q-item>
    </q-list>
  </q-drawer>

  <q-page-container>
    <q-page class="q-pa-md">
      Контент страницы
    </q-page>
  </q-page-container>

  <q-footer elevated>
    <div class="text-center q-pa-sm">Футер приложения</div>
  </q-footer>
</q-layout>

Особенности:

  • Атрибут view задает расположение областей (hHh lpR fFf — верхний хедер, левый drawer, футер фиксирован).
  • v-model="drawerOpen" связывает видимость боковой панели с реактивной переменной.
  • q-page-container автоматически подстраивает контент под имеющиеся шапку и боковую панель.

Композиция через вложенные компоненты

Quasar поощряет разделение интерфейса на небольшие компоненты. Например, создаются отдельные компоненты для карточек, таблиц и форм:

<!-- CardComponent.vue -->
<template>
  <q-card bordered>
    <q-card-section>
      <div class="text-subtitle1">{{ title }}</div>
      <div>{{ description }}</div>
    </q-card-section>
    <q-card-actions align="right">
      <q-btn flat label="Подробнее" @click="$emit('view')"/>
    </q-card-actions>
  </q-card>
</template>

<script setup>
defineProps({
  title: String,
  description: String
});
</script>

Использование в родительском компоненте:

<template>
  <div class="q-gutter-md">
    <CardComponent
      v-for="item in items"
      :key="item.id"
      :title="item.title"
      :description="item.description"
      @view="openItem(item.id)"
    />
  </div>
</template>

<script setup>
import CardComponent from './CardComponent.vue';
import { ref } from 'vue';

const items = ref([
  { id: 1, title: 'Задача 1', description: 'Описание задачи 1' },
  { id: 2, title: 'Задача 2', description: 'Описание задачи 2' }
]);

function openItem(id) {
  console.log('Открыть элемент', id);
}
</script>

Преимущества композиции:

  • Переиспользуемость компонентов.
  • Легкость тестирования и поддержки.
  • Четкое разделение ответственности между визуальными и логическими блоками.

Слоты для гибкой кастомизации

Quasar поддерживает слоты, которые позволяют вставлять пользовательский контент в готовые компоненты:

<q-btn color="primary">
  <template v-slot:prepend>
    <q-icon name="star" />
  </template>
  Кнопка с иконкой
</q-btn>

Ключевые моменты использования слотов:

  • prepend и append — стандартные слоты для добавления иконок.
  • Пользовательские слоты создаются через <template v-slot:имя>.
  • Слоты обеспечивают гибкость без изменения исходного компонента.

Динамическое создание компонентов через v-for и v-if

Композиция компонентов часто подразумевает динамическое отображение элементов. Используются стандартные директивы Vue:

<q-list>
  <q-item v-for="task in tasks" :key="task.id" clickable>
    <q-item-section>{{ task.name }}</q-item-section>
    <q-item-section side>
      <q-btn dense flat icon="delete" @click="removeTask(task.id)"/>
    </q-item-section>
  </q-item>
</q-list>

Особенности:

  • Позволяет создавать интерфейсы на основе данных.
  • Совместно с событиями (@click) обеспечивает интерактивность.
  • В сочетании со слотами можно полностью кастомизировать внешний вид элементов.

Стилизация и адаптивность

Quasar использует CSS Utility классы, которые позволяют быстро управлять отступами, цветами и расположением элементов.

Примеры:

  • q-pa-md — внутренний отступ среднего размера.
  • q-mt-sm — небольшой верхний отступ.
  • text-center — выравнивание текста по центру.
  • col-6 и col-12 — сетка для адаптивного дизайна.

Комбинируя utility-классы с компонентами, можно строить сложные интерфейсы без написания большого количества CSS.


Комбинация с Vue Composition API

Для управления состоянием в составе компонентов Quasar удобно использовать Composition API:

<script setup>
import { ref, computed } from 'vue';

const tasks = ref([
  { id: 1, name: 'Задача A', done: false },
  { id: 2, name: 'Задача B', done: true }
]);

const completedTasks = computed(() => tasks.value.filter(t => t.done));

function toggleTask(id) {
  const task = tasks.value.find(t => t.id === id);
  if (task) task.done = !task.done;
}
</script>

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


Практические рекомендации

  • Разделять интерфейс на логические компоненты: карточки, таблицы, формы, панели навигации.
  • Использовать QLayout и QPageContainer как основу для структурирования приложения.
  • Применять слоты для добавления кастомного контента.
  • Оптимизировать повторное использование компонентов через props и события.
  • Совмещать Quasar компоненты с Composition API для управления состоянием и реактивностью.

Эта методика позволяет создавать масштабируемые, переиспользуемые и поддерживаемые интерфейсы, полностью используя мощь Quasar Framework и Vue.js.