Je construis actuellement une application vue et Im en utilisant axios. J'ai une icône de chargement que je montre avant de faire chaque appel et que je me cache après.
Je me demande simplement s'il existe un moyen de le faire à l'échelle mondiale, donc je n'ai pas à écrire l'icône de chargement afficher/masquer à chaque appel?
Voici le code que j'ai en ce moment:
context.dispatch('loading', true, {root: true});
axios.post(url,data).then((response) => {
// some code
context.dispatch('loading', false, {root: true});
}).catch(function (error) {
// some code
context.dispatch('loading', false, {root: true});color: 'error'});
});
J'ai vu sur les documents axios qu'il y a des "intercepteurs" mais je ne sais pas s'ils sont au niveau global ou à chaque appel.
J'ai également vu ce post pour une solution jquery, je ne sais pas comment l'implémenter sur vue cependant:
$('#loading-image').bind('ajaxStart', function(){
$(this).show();
}).bind('ajaxStop', function(){
$(this).hide();
});
Je configurerais intercepteurs Axios dans le hook de cycle de vie created
du composant racine (par exemple App.vue
):
created() {
axios.interceptors.request.use((config) => {
// trigger 'loading=true' event here
return config;
}, (error) => {
// trigger 'loading=false' event here
return Promise.reject(error);
});
axios.interceptors.response.use((response) => {
// trigger 'loading=false' event here
return response;
}, (error) => {
// trigger 'loading=false' event here
return Promise.reject(error);
});
}
Étant donné que vous pouvez avoir plusieurs demandes Axios simultanées, chacune avec des temps de réponse différents, vous devez suivre le nombre de demandes pour gérer correctement l'état de chargement global (incrémenter sur chaque demande, décrémenter lorsque chaque demande se résout et effacer l'état de chargement lorsque le compte atteint 0):
data() {
return {
refCount: 0,
isLoading: false
}
},
methods: {
setLoading(isLoading) {
if (isLoading) {
this.refCount++;
this.isLoading = true;
} else if (this.refCount > 0) {
this.refCount--;
this.isLoading = (this.refCount > 0);
}
}
}
Je pense que vous êtes sur la bonne voie avec l'événement dispatch lorsque l'appel ajax démarre et se termine.
La façon dont je pense que vous pouvez vous y prendre est d'intercepter l'appel XMLHttpRequest en utilisant des intercepteurs axios comme ceci:
axios.interceptors.request.use(function(config) {
// Do something before request is sent
console.log('Start Ajax Call');
return config;
}, function(error) {
// Do something with request error
console.log('Error');
return Promise.reject(error);
});
axios.interceptors.response.use(function(response) {
// Do something with response data
console.log('Done with Ajax call');
return response;
}, function(error) {
// Do something with response error
console.log('Error fetching the data');
return Promise.reject(error);
});
function getData() {
const url = 'https://jsonplaceholder.typicode.com/posts/1';
axios.get(url).then((data) => console.log('REQUEST DATA'));
}
function failToGetData() {
const url = 'https://bad_url.com';
axios.get(url).then((data) => console.log('REQUEST DATA'));
}
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<button onclick="getData()">Get Data</button>
<button onclick="failToGetData()">Error</button>
Aussi pour Nuxt, le plugin $ axios peut essayer de cette façon
PKG: ['@ nuxtjs/axios'] ....
Plugins internes/axios.js
export default ({ app, $axios ,store }) => {
const token = app.$cookies.get("token")
if (token) {
$axios.defaults.headers.common.Authorization = "Token " + token
}
$axios.interceptors.request.use((config) => {
store.commit("SET_DATA", { data:true, id: "loading" });
return config;
}, (error) => {
return Promise.reject(error);
});
$axios.interceptors.response.use((response) => {
store.commit("SET_DATA", { data:false, id: "loading" });
return response;
}, (error) => {
return Promise.reject(error);
});
}
Dans le magasin/index.js
export default {
state: () => ({
loading: false
}),
mutations: {
SET_DATA(state, { id, data }) {
state[id] = data
}
},
actions: {
async nuxtServerInit({ dispatch, commit }, { app, req , redirect }) {
const token = app.$cookies.get("token")
if (token) {
this.$axios.defaults.headers.common.Authorization = "Token " + token
}
let status = await dispatch("authentication/checkUser", { token })
if(!status) redirect('/aut/login')
}
}
}
Cet exemple est accompagné d'un chèque de jeton avec $ axios et store store
j'espère l'utiliser pleinement.