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
- Create a dedicated event bus Vue instance in
eventhub.js
(as recommended in docs):
export const eventHub = new Vue();
- 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;
}
- 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.
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
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.