greyby / vue-spinner

vue spinners

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to use vue-spinner in interceptors of axios

LJade opened this issue · comments

I want to realize the loading shows when ajax request occurred but close when get ajax response. Vue-spinner is beautiful but I can't find the document to control the spinner switch.Also, options config is not friendly.Is there any solution? Thank you very much!

I was going to ask something also, before I realized the maintainer of this project doesn't seem to have discovered the "issues" tab. Anyway, this is how I would use it:

<pulse-loader :loading="loading" :color="color" :size="size"></pulse-loader>
data () {
  return {
    loading : true
   }
},

methods: {
  getSomething () {
    axios.get('/api').then(res => {
      if(res.data) {
        ...
        this.loading = false
      }
    }).catch(err => {
      if(err.msg) {
        ...
        this.loading = false
      }
    })
  }
}

@samayo I have been resolved this issues.My axios config file is a single '.js' ,not depend on '.vue' file.
I used vuex to control the switch,thank very much

  1. Create a dedicated event bus Vue instance in eventhub.js (as recommended in docs):
export const eventHub = new Vue();
  1. Import it in your Axios module and emit events with interceptors:
import { eventHub } from 'eventhub'

function createAxios() {
    const axios = Axios.create({ ... });
    axios.interceptors.request.use(
        conf => {
            eventHub.$emit('before-request');
            return conf;
        },
        error => {
            eventHub.$emit('request-error');
            return Promise.reject(error);
        }
    );
    axios.interceptors.response.use(
        response => {
            eventHub.$emit('after-response');
            return response;
        },
        error => {
            eventHub.$emit('response-error');
            return Promise.reject(error);
        }
    );
    return axios;
}
  1. Listen to the events in your App.vue or any other component and show/hide the spinner according to the event:
import { eventHub } from 'utils/eventhub'

export default {
    data () {
        return { spinnerVisible: false }
    },
    methods: {
        showSpinner() {
            console.log('show spinner');
            this.spinnerVisible = true;
        },
        hideSpinner() {
            console.log('hide spinner');
            this.spinnerVisible = false;
        }
    },
    created() {
        eventHub.$on('before-request', this.showSpinner);
        eventHub.$on('request-error',  this.hideSpinner);
        eventHub.$on('after-response', this.hideSpinner);
        eventHub.$on('response-error', this.hideSpinner);
    },
    beforeDestroy() {
        eventHub.$off('before-request', this.showSpinner);
        eventHub.$off('request-error',  this.hideSpinner);
        eventHub.$off('after-response', this.hideSpinner);
        eventHub.$off('response-error', this.hideSpinner);
    }
}

But as @LJade said, it is better to use Vuex rather than the event bus.

Is it possible to add vue-spinner to a single axios util class in which all of the other classes can make calls from this util class?
If yes, how?
@LJade @mrts

If you are using vue CLI:

in your main.js:
Axios request interceptor

axios.interceptors.request.use(function (config) {
store.commit("load", true) //vuex mutation set loading state to true
return config;
}, function (error) {
return Promise.reject(error);
});

Axios response interceptor

axios.interceptors.response.use(function (config) {
store.commit("load", false) //vuex mutation set loading state to false
return config;
}, function (error) {
return Promise.reject(error);
});

create a component xxx and register it..

in your App.vue

<script> import Navbar from '@/components/Navbar.vue' export default { name: 'app', components: { Navbar, }, computed:{ load(){ return this.$store.getters.isLoading }, } } </script>

Now this automatically displays loading symbol on every axios request

Hello @mrts Thanks for the reply, the approach you explained in Vue 2 with event bus... can you please help me to implement same thing in Vue 3 with mitt library.