How to call a custom global function using composition api | vue3
Asked Answered
S

2

9

In main.js, I set axios as a global function.


//main.js
import { createApp } from 'vue';
import App from './App.vue';
import axios from 'axios';
const app = createApp(App);
app.config.globalProperties.$http = axios;
app.mount('#app');

The thing is how do I call this function in a component using composition api?


<script>
export default {
  setup() {
   //how do I call the `axios` global function?
 };
</script>

Shaunteshave answered 19/8, 2021 at 13:37 Comment(2)
You should be able to use it via $http but why don't you import it in the component? – Phosphor
Check here pls – Weaponeer
E
13

First off, is it not possible to simply import axios in the components where it's needed? Using global properties is discouraged in Vue 3 with the composition API. With that said, this is still possible in a few ways:

Importing where needed

The ideal method, as I mentioned earlier, is simply to

import axios from 'axios'

in components where it is needed.

Provide/inject

If, for whatever reason, you do need to provide Axios globally from your app, another way to do so is to use the Provide/Inject pattern.

In your App.vue:

import { provide } from 'vue'

export default {
    setup() {
        provide('axios', axios);
    }
}

And in whatever components need it:

import { inject } from 'vue'

export default {
    setup() {
        const axios = inject('axios');
    }
}

getCurrentInstance() (discouraged)

Per the Vue documentation,

Usage of getCurrentInstance is strongly discouraged in application code. Do NOT use it as an escape hatch to get the equivalent of this in Composition API.

However, if you really want to maintain it as a global property, you can use it as follows:

import { getCurrentInstance } from 'vue';

export default {
    setup() {
        const app = getCurrentInstance();
        const axios = app.appContext.config.globalProperties.$http;
Equiponderance answered 20/8, 2021 at 17:45 Comment(2)
All points are valid, however I have some concerns with defining import axios as the "ideal solution": when it comes to modularization a core principle is to reduce internal coupling among them. This means that a module should not depend (thus include) directly another module but should rather ask the app to "provide" the single responsible for specific logic. Thus provide / inject solution looks more appropriate to me, except that if you want to implement it with TS you will end up coupling modules anyway (consumer module needs to import the injection key anyway before injecting) πŸ˜• – Morisco
Marco is correct... The idea behind provide/inject is to allow for dependency injection (DI) in Vue components. If you want every component in your Vue app to have access to the same instance of axios, but also have it have an agnostic custom name like http, so it can be switched out to another API identical/similar library, then you'd use app.provide('http', axios) in the OP's first code block. You can then proceed to use const http = inject('http'); in any components in your application, and it'll just work. Now, if you want to change Axios, you only do so in one place. – Claudelle
N
-7

You can call it like so:

this.$http.get('http://127.0.0.1/api')
Nonparticipating answered 19/8, 2021 at 15:36 Comment(2)
but this is undefined in setup function – Minard
this works in options api – Lerma

© 2022 - 2024 β€” McMap. All rights reserved.