Создание API клиента

Для интеграции с внешними API в Quasar используется комбинация возможностей Vue.js и стандартных библиотек для работы с HTTP-запросами, таких как axios или встроенный fetch. Quasar не ограничивает выбор, однако рекомендуемым подходом является использование axios благодаря удобной настройке интерцепторов и обработке ошибок.

import axios from 'axios';

const apiClient = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json'
  }
});

В этом примере создается отдельный экземпляр клиента с предустановленным базовым URL и таймаутом. Это позволяет централизованно управлять всеми запросами и упрощает их изменение при необходимости.

Интерцепторы запросов и ответов

Интерцепторы позволяют обрабатывать запросы и ответы глобально, что удобно для добавления токенов авторизации или логирования ошибок.

apiClient.interceptors.request.use(config => {
  const token = localStorage.getItem('authToken');
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
}, error => Promise.reject(error));

apiClient.interceptors.response.use(response => response, error => {
  if (error.response && error.response.status === 401) {
    // обработка неавторизованного запроса
  }
  return Promise.reject(error);
});

Создание модульной структуры API

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

/src/api/
  ├─ index.js
  ├─ auth.js
  ├─ users.js
  └─ products.js

Пример модуля auth.js:

import apiClient from './index';

export const login = (credentials) => {
  return apiClient.post('/auth/login', credentials);
};

export const logout = () => {
  return apiClient.post('/auth/logout');
};

Пример модуля users.js:

import apiClient from './index';

export const getUsers = (params) => {
  return apiClient.get('/users', { params });
};

export const getUserById = (id) => {
  return apiClient.get(`/users/${id}`);
};

export const createUser = (userData) => {
  return apiClient.post('/users', userData);
};

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

Обработка ошибок и повторные запросы

Quasar и Vue позволяют использовать реактивность для глобального состояния ошибок:

import { ref } from 'vue';

export const apiError = ref(null);

apiClient.interceptors.response.use(
  response => response,
  error => {
    apiError.value = error.response?.data?.message || error.message;
    return Promise.reject(error);
  }
);

Для повторных запросов можно использовать стратегию “retry” с небольшими задержками:

import axiosRetry from 'axios-retry';

axiosRetry(apiClient, { retries: 3, retryDelay: (retryCount) => retryCount * 1000 });

Использование API клиента в компонентах Quasar

Подключение модулей API осуществляется через импорт:

<template>
  <q-page>
    <q-btn label="Загрузить пользователей" @click="loadUsers" />
    <ul>
      <li v-for="user in users" :key="user.id">{{ user.name }}</li>
    </ul>
  </q-page>
</template>

<script setup>
import { ref } from 'vue';
import { getUsers } from 'src/api/users';

const users = ref([]);

const loadUsers = async () => {
  try {
    const response = await getUsers();
    users.value = response.data;
  } catch (err) {
    console.error('Ошибка загрузки пользователей:', err);
  }
};
</script>

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

Работа с асинхронными операциями и загрузкой данных

Для улучшения UX удобно добавлять индикаторы загрузки:

const loading = ref(false);

const loadUsers = async () => {
  loading.value = true;
  try {
    const response = await getUsers();
    users.value = response.data;
  } finally {
    loading.value = false;
  }
};

Quasar предоставляет готовые компоненты, такие как q-spinner или q-linear-progress, которые можно использовать для визуализации состояния загрузки.

Настройка глобальных параметров API

Можно централизованно управлять URL, токенами и кэшированием:

const apiClient = axios.create({
  baseURL: import.meta.env.VITE_API_URL,
  timeout: 15000,
  headers: {
    'Content-Type': 'application/json'
  }
});

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

Интеграция с Vuex и Pinia

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

import { defineStore } from 'pinia';
import { getUsers } from 'src/api/users';

export const useUserStore = defineStore('user', {
  state: () => ({
    users: [],
    loading: false
  }),
  actions: {
    async fetchUsers() {
      this.loading = true;
      try {
        const response = await getUsers();
        this.users = response.data;
      } finally {
        this.loading = false;
      }
    }
  }
});

Такое решение позволяет легко интегрировать API в масштабные приложения Quasar, обеспечивая управление состоянием и обработку ошибок на глобальном уровне.