【问题标题】:Axios ajax, show loading when making ajax requestaxios ajax,发出ajax请求时显示加载
【发布时间】:2018-11-18 23:44:26
【问题描述】:

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

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

这是我现在的代码:

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

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

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

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

【问题讨论】:

  • 拦截器可以在全局范围内使用,也可以仅用于某些请求(如果您愿意)(只需 create an instance 与它们一起使用,并且仅在您希望请求更改加载状态时使用此实例)。但是......我不确定让每个请求打开和关闭加载状态的概念。在某些情况下,您可能希望同时运行多个请求。如果其中一个比另一个快,它会将加载状态设置为 false,而另一个仍处于挂起状态。在您的情况下可能不是问题,但考虑到这一点很重要。
  • 是否有更通用的方法来检测是否有任何未决请求?
  • 可能还有其他方法,但我能想到的一种方法是在您的商店(或其他地方,例如您初始化 axios)中有一个待处理的请求计数器。将其初始化为零,每次启动请求时,添加1,并将加载状态设置为true。请求完成后(解决或拒绝),减去1,只有当计数器等于0时,才将加载状态设置为false。

标签: javascript vue.js vuejs2 axios


【解决方案1】:

我会在根组件的created 生命周期挂钩中设置Axios interceptors(例如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);
  });
}

由于您可能有多个并发 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

【讨论】:

    【解决方案2】:

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

    我认为你可以这样做的方法是使用 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>

    【讨论】:

      【解决方案3】:

      对于 Nuxt 和$axios plugin

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

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

      存储/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')
          }
        }
      }
      

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

      【讨论】:

        猜你喜欢
        • 2011-12-14
        • 2012-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-10
        • 2019-05-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多