Глобальное использование axios в Vue 3 с помощью provide/inject (composition API)

Vue 2

В Vue 2 нам бы пришлось использовать Vue.prototype, чтобы добавить глобальные свойства к экземпляру Vue. Но в Vue 3 мы получили »Composition API»

Итак, рекомендуемый способ добавления глобальных свойств с помощью composition api это использовать provide/inject. Поскольку config.globalProperties рассматривается как аварийный выход.

config.globalProperties

Свойства config.globalPropertiesпредназначены для репликации поведения Vue.prototype. В функции setupпросто импортируйте то, что вам нужно, или явно используйте provide/inject, чтобы предоставить свойства приложению.

Создаем файл /api/index.ts

import axios, { AxiosInstance } from 'axios';

const apiClient: AxiosInstance = axios.create({
    baseURL: import.meta.env.VITE_BASE_URL,
    headers: {
        'Content-type': 'application/json'
    }
});

export default apiClient;

Это наш глобальный экземпляр Axios с опциями

Создаем файл /api/symbols.ts

import { InjectionKey } from 'vue';
import { AxiosInstance } from 'axios';

export const AxiosKey: InjectionKey = Symbol('http');

Это необходимо для возможности типизации Provide/inject

В файле main.ts

import http from '@/api/index';
import { AxiosKey } from '@/api/symbols';

createApp(App).provide(AxiosKey, http)

Мы предоставляем наш экземпляр Axios глобально, используя Injection Key — AxiosKey, поэтому теперь он типизируется. В противном случае вам пришлось бы вводить типы каждый раз, при использовании inject ()

Создаем файл /api/injectTyped.ts

import { inject, InjectionKey } from 'vue';

/* Функция для работы с неопределенными значениями в inject() */
export function injectStrict(key: InjectionKey, fallback?: T) {
    const resolved = inject(key, fallback);
    if (!resolved) {
        throw new Error(`Could not resolve ${key.description}`);
    }
    return resolved;
}

итоговая структура файлов

итоговая структура файлов

Создаем функцию composable в /composables/Api.ts

import { injectStrict } from '@/api/injectTyped';
import { AxiosKey } from '@/api/symbols';

/* Для глобального доступа и типизации запросов */
export const useApi = () => injectStrict(AxiosKey);

Использование

Теперь у нас есть удобная глобальная и типизируемая прослойка по работе с API

© Habrahabr.ru