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.
1. Create a file called http.ts (you can name it as you wish):
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.
2. Create a file symbols.ts
import { InjectionKey } from 'vue'
import { AxiosInstance } from 'axios'
export const AxiosKey: InjectionKey<AxiosInstance> = Symbol('http')
This is required to type our Provide/Inject.
3. Go to main.ts
// 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()
4. Create a function to deal with undefined values, when 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
5. Using our global axios instance inside a component:
<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>
Top comments (3)
Great Demo. Thanks
Excellent article that stopped me pulling my hair - thanks!
What would be the best approach to use same axios instance on .js file with inject?