web-dev-qa-db-ja.com

Axios Ajax、Ajaxリクエストを行う際の読み込みを表示

現在axiosを使用してvueアプリとImを作成しています。各呼び出しを行う前に表示し、後に非表示にする読み込みアイコンがあります。

グローバルにこれを行う方法があるので、呼び出しごとに表示/非表示の読み込みアイコンを書く必要はありませんか?

これは私が今持っているコードです:

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 docsには「インターセプター」がありますが、IIはそれらがグローバルレベルにあるのか、各呼び出しにあるのかわかりません。

私はjqueryソリューションのこの投稿を見ましたが、vueで実装する方法はわかりませんが:

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

ルートコンポーネントのcreatedライフサイクルフックに Axiosインターセプター を設定します(例: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);
    }
  }
}

デモ

18
tony19

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

Nuxtの場合、プラグイン$ axiosはこの方法を試すことができます

PKG:['@ nuxtjs/axios'] ....

内部plugins/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内


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 storeを使用したトークンチェックが伴います

使い切ってください。

1