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
Axios ajax, show loading when making ajax request
提问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);
}
}
}
回答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 的令牌检查

