Создание библиотеки композаблов

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

Создание базового композабла

Базовый композабл представляет собой функцию, возвращающую объект с реактивными свойствами и методами. В Quasar для реактивности используется стандартная система Vue 3: ref, reactive, computed.

import { ref, computed } from 'vue';

export function useCounter(initialValue = 0) {
  const count = ref(initialValue);

  const increment = () => count.value++;
  const decrement = () => count.value--;
  const double = computed(() => count.value * 2);

  return { count, increment, decrement, double };
}

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

  • ref создаёт реактивное значение.
  • computed позволяет вычислять значения на основе состояния.
  • Методы инкапсулируют логику изменения состояния.

Организация сложной библиотеки композаблов

Для крупных приложений рекомендуется разбивать библиотеку на модули:

/composables
  /counter
    index.js
  /auth
    index.js
  /theme
    index.js

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

// /composables/auth/index.js
import { ref } from 'vue';

export function useAuth() {
  const user = ref(null);
  const isLoggedIn = computed(() => !!user.value);

  const login = (username, password) => {
    // логика авторизации
  };

  const logout = () => { user.value = null };

  return { user, isLoggedIn, login, logout };
}

Принципы модульности:

  • Каждый композабл должен решать одну задачу.
  • Состояние и методы внутри композабла не должны напрямую зависеть от компонентов.
  • Для асинхронных операций можно использовать async/await внутри методов.

Интеграция с Quasar Framework

Quasar предоставляет утилиты и плагины, которые можно использовать внутри композаблов. Например, работа с уведомлениями, роутером или хранилищем состояния Vuex/Pinia.

import { useQuasar } from 'quasar';
import { ref } from 'vue';

export function useNotifier() {
  const $q = useQuasar();
  const messages = ref([]);

  const notify = (message, color = 'primary') => {
    $q.notify({ message, color });
    messages.value.push({ message, color, timestamp: Date.now() });
  };

  return { messages, notify };
}

Особенности использования:

  • useQuasar() обеспечивает доступ к глобальным методам и компонентам Quasar.
  • Композаблы могут аккумулировать состояние и создавать журнал действий.
  • Такой подход позволяет изолировать работу с Quasar от компонентов.

Паттерны и лучшие практики

  1. Разделение состояния и логики – состояние хранится в ref/reactive, а логика обрабатывается методами композабла.
  2. Переиспользование через функции – композабл не зависит от конкретного компонента.
  3. Инкапсуляция побочных эффектов – асинхронные операции и взаимодействие с API должны быть внутри композаблов.
  4. Тестируемость – функции легко тестируются без подключения к компонентам Vue.

Создание параметризованных композаблов

Композаблы могут принимать параметры для гибкой конфигурации:

export function useFetch(url, options = {}) {
  const data = ref(null);
  const loading = ref(false);
  const error = ref(null);

  const fetchData = async () => {
    loading.value = true;
    error.value = null;
    try {
      const res = await fetch(url, options);
      data.value = await res.json();
    } catch (err) {
      error.value = err;
    } finally {
      loading.value = false;
    }
  };

  return { data, loading, error, fetchData };
}

Преимущества:

  • Композабл становится универсальным инструментом для любых запросов.
  • Состояние запроса полностью инкапсулировано.
  • Методы возвращают реактивные объекты, легко связываемые с компонентами.

Расширение композаблов

Композаблы можно объединять для создания сложных функциональных блоков:

import { useCounter } from './counter';
import { useNotifier } from './notifier';

export function useSmartCounter() {
  const counter = useCounter();
  const notifier = useNotifier();

  const incrementAndNotify = () => {
    counter.increment();
    notifier.notify(`Счётчик увеличен: ${counter.count.value}`);
  };

  return { ...counter, incrementAndNotify };
}

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

Документирование библиотеки

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

  • Описание функционала.
  • Входные параметры.
  • Возвращаемые объекты и методы.
  • Примеры использования.
/**
 * useCounter - композабл для управления счётчиком
 * @param {number} initialValue - начальное значение
 * @returns {Object} count, increment, decrement, double
 */

Это облегчает интеграцию в крупные проекты и работу командного разработчика.


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