Javascript axios ajax,在发出ajax请求时显示加载

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/50768678/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:40:26  来源:igfitidea点击:

Axios ajax, show loading when making ajax request

javascriptvue.jsvuejs2axios

提问by Brad

I'm currently building a vue app and Im using axios. I have a loading icon which i show before making each call and hide after.

我目前正在构建一个 vue 应用程序,我正在使用 axios。我有一个加载图标,我在每次调用之前显示它并在之后隐藏。

Im just wondering if there is a way to do this globally so I dont have to write the show/hide loading icon on every call?

我只是想知道是否有办法在全局范围内执行此操作,因此我不必在每次调用时都编写显示/隐藏加载图标?

This is the code I have right now:

这是我现在拥有的代码:

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

I have seen on the axios docs there are "interceptors" but II dont know if they are at a global level or on each call.

我在 axios 文档上看到有“拦截器”,但我不知道它们是在全局级别还是在每次调用中。

I also saw this post for a jquery solution, not sure how to implement it on vue though:

我也看到了这篇关于 jquery 解决方案的帖子,但不确定如何在 vue 上实现它:

$('#loading-image').bind('ajaxStart', function(){
    $(this).show();
}).bind('ajaxStop', function(){
    $(this).hide();
});

回答by tony19

I would setup Axios interceptorsin the root component's createdlifecycle hook (e.g. App.vue):

我会在根组件的生命周期钩子(例如)中设置Axios 拦截器createdApp.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);
  });
}

Since you could have multiple concurrent Axios requests, each with different response times, you'd have to track the request count to properly manage the global loading state (increment on each request, decrement when each request resolves, and clear the loading state when count reaches 0):

由于您可能有多个并发 Axios 请求,每个请求都有不同的响应时间,因此您必须跟踪请求计数以正确管理全局加载状态(每个请求增加,每个请求解决时减少,计数时清除加载状态达到 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);
    }
  }
}

demo

演示

回答by Shahar

I think you are on the right path with dispatch event when ajax call start and finish.

我认为当 ajax 调用开始和结束时,你的调度事件是正确的。

The way that I think you can go about it is to intercept the XMLHttpRequest call using axios interceptors like so:

我认为您可以采用的方法是使用 axios 拦截器拦截 XMLHttpRequest 调用,如下所示:

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>

回答by Davod Aslanifakor

For Nuxtwith $axios plugin

对于Nuxt$爱可信的插件

modules: ['@nuxtjs/axios', ...]

模块:['@nuxtjs/axios', ...]

plugins/axios.js

插件/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);
  })
}

store/index.js

商店/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')
    }
  }
}

This example is accompanied by a token check with $axios and store

这个例子伴随着 $axios 和 store 的令牌检查