web-dev-qa-db-fra.com

Axios ajax, afficher le chargement lors de la demande ajax

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();
});
6
Brad

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);
    }
  }
}

démo

18
tony19

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>
4
Shahar

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.

1
Davod Aslanifakor