In a Vue 2 we had to use Vue.prototype in order to add global properties to a Vue instance. But in a Vue 3 we got "Composition API".
So, using a composition api, recommended way to add global properties, is by using provide/inject. Because config.globalProperties considered as an escape hatch
Let's get started.
import axios, { AxiosInstance } from 'axios'
const apiClient: AxiosInstance = axios.create({
baseURL: 'https://api.openbrewerydb.org',
headers: {
'Content-type': 'application/json'
}
})
export default apiClient
It's our global Axios instance with the options.
import { InjectionKey } from 'vue'
import { AxiosInstance } from 'axios'
export const AxiosKey: InjectionKey<AxiosInstance> = Symbol('http')
This is required to type our Provide/Inject.
// libs
import http from '@/http'
import { AxiosKey } from '@/symbols'
const app = createApp(App)
app.provide(AxiosKey, http)
We're providing our Axios instance globally here, using InjectionKey - AxiosKey, so it's typed now. Otherwise you would have to provide types every time you use inject()
import { inject, InjectionKey } from 'vue'
export function injectStrict<T>(key: InjectionKey<T>, fallback?: T) {
const resolved = inject(key, fallback)
if (!resolved) {
throw new Error(`Could not resolve ${key.description}`)
}
return resolved
}
It was found in this useful blog post
<script setup lang="ts">
import { ref, onMounted } from 'vue'
// typing inject
import { injectStrict } from '@/utils/injectTyped'
import { AxiosKey } from '@/symbols'
interface Breweries {
id: string
name: string
}
const http = injectStrict(AxiosKey) // it's typed now
const breweries = ref<Breweries[]>([])
onMounted(async () => {
const resp = await http.get<Breweries[]>('/breweries')
breweries.value = resp.data
})
</script>