【vue】切換路由頁面時,中止上個路由頁面未返回資料的請求
阿新 • • 發佈:2019-02-16
背景:
通常情況下,介面返回會比較快,不會出現此類狀況。
但是也有可能是後臺介面也依賴於上游介面,那麼處理過程中可能會有一些延遲之類的問題。
當用戶的某些操作,比如快速切換選單,某些選單一進入頁面後,就會向後臺傳送請求,在請求未拿到資料時,就被使用者切換到下個路由頁面,那麼上個路由頁面的請求,在未處理的情況下,就還是處於在傳送中,為了處理請求的效率,所以做了些處理。
我的專案是通過axios封裝請求,此處要用到axios中的cancelToken,我通過網上整理的,蒐集了兩種解決辦法,一種是取消一個請求,另一種是取消上個路由中所有未返回的請求。
下面我貼下部分程式碼(取消所有未返回的請求):
xhttp.js,是專案中一個封裝好的axios的js
import axios form 'axios'
// 定義全域性變數clearRequest,在route.js中要用到
const clearRequest = {
source: {
token: null,
cancel: null
}
}
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
// 配置傳送請求攔截器
axios.interceptors.request.use(config => {
config.cancelToken = clearRequest.source. token;// 這句很重要
return config
}, error => {
rerurn Promise.reject(error)
})
// ...此處省略其他程式碼
// 封裝通用請求
export default {
post (url,data) {
return axios({
method: 'post',
url,
data: data,
timeout: 30000,
cancelToken: source.token,// 這句很重要
headers: {
'X-Requested-With': 'XMLHttpRequest' ,
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
.then( (res) => {} )
.catch( (res) => {} )
})
},
get (url,data) {
method: 'get',
url,
data: data,
timeout: 30000,
cancelToken: source.token,// 這句很重要
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
.then( (res) => {} )
.catch( (res) => {} )
},
clearRequest
}
每次路由變化前,執行cancel方法並且更新cancelToken。
route.js
import Vue from 'vue'
import Router from 'vue-router'
import { routers } from './route'
import axios from 'axios'
import http from '@/http/xhttp'
Vue.use(Router)
// 路由配置
const RouterConfig = {
mode: 'history',
routes: routers
}
export const router = new Router(RouterConfig)
router.beforeEach((to, from, next) => {
// ...此處其他程式碼省略
// 切換路由時清空上個路由未完成的所有請求
const CancelToken = axios.CancenlToken;
http.clearRequest.source.cancel && http.clearRequest.source.cancel();
http.clearRequest.source = CancelToken.source();
next();
// ...此處其他程式碼省略
})
Vue.prototype.$ajax=axios;
const CancelToken = axios.CancelToken;
let cancel;
let cancelAjaxText = '中斷成功';
Vue.prototype.post = function(url,data,loading){
var ajax = Vue.prototype.$ajax({
method: 'post',
url:url,
data: data,
cancelToken: new CancelToken(c => { //強行中斷請求要用到的
cancel = c
})
}).then(res =>res.data,res=>{ //中斷請求和請求出錯都會走這裡,我這裡用 cancelAjaxText 來區別
if(res.message == cancelAjaxText){
return {status : false,msg:cancelAjaxText}
}else{
this.$confirm('登入過時,是否重新登入', '提示', {
confirmButtonText: '確定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
window.location.href = Vue.prototype.url_head + '/';
}).catch(() => {
});
}
})
return ajax;
};
接入 axios ,在POST方法里加入 cancelToken 資料,在上面else中,中斷請求和請求出錯都會走那裡,所以用一個msg來識別(因為介面返回中也有一個msg,統一一下);
以下是 中斷請求的方法,放在 路由切換的監聽 router.beforeEach 中 ,cancel 是中斷的方法,在post 的 cancelToken 裡面拿出來的
Vue.prototype.cancelAjax = function(){ //切換頁面強行中斷請求 router.beforeEach中用到
if(cancel){
cancel(cancelAjaxText);
}
}
router.beforeEach((to, from, next) => {
<span style="white-space:pre;"> </span>Vue.prototype.cancelAjax()
next();
});