vue路由切換時(shí)取消之前的所有請(qǐng)求操作
在main.js文件里
import router from ’router/’;import Vue from ’vue’;Vue.Cancel = [];router.beforeEach((to, from, next) => { while (Vue.Cancel.length > 0) { Vue.Cancel.shift()(’cancel’); } next();})
ajax文件
import Vue from ’vue’;import axios from ’axios’;import VueAxios from ’vue-axios’;Vue.use(VueAxios, axios);// 導(dǎo)入封裝的回調(diào)函數(shù)import { cbs, gbs} from ’config/’;// 動(dòng)態(tài)設(shè)置本地和線上接口域名Vue.axios.defaults.baseURL = gbs.host;/** * 封裝axios的通用請(qǐng)求 * @param {string} type get或post * @param {string} url 請(qǐng)求的接口URL * @param {object} data 傳的參數(shù),沒有則傳空對(duì)象 * @param {object} urlParams url傳參 * @param {Function} fn 回調(diào)函數(shù) * @param {boolean} tokenFlag 是否需要攜帶token參數(shù),為true,不需要;false,需要。一般除了登錄,都需要 */export default function ({ type, path, data, params, urlParams, fn, errFn, tokenFlag, headers, opts} = {}) { var options = { method: type, url: path, params: params, headers: headers && typeof headers === ’object’ ? headers : {}, cancelToken: new axios.CancelToken(function (cancel) { Vue.Cancel && Vue.Cancel.push(cancel) }) }; //檢測(cè)接口權(quán)限 var api_flag = true; if (options.url && options.url.indexOf(gbs.host) && this.$store.state.user.userinfo.access_status === 1) { var url = options.url.replace(gbs.host, ’’); var api_routers = this.$store.state.user.userinfo.api_routers; if (!api_routers || !api_routers.constructor === Object || !api_routers[url]) { api_flag = false; } } var urlParamsArray = []; if (api_flag === true) { options[type === ’get’ ? ’params’ : ’data’] = data; // 用于url傳參 if (typeof (urlParams) == 'object') { for (var k in urlParams) { urlParamsArray.push(k + ’=’ + urlParams[k]) } options.url += ’?’ + urlParamsArray.join(’&’); } if (typeof (urlParams) == 'string' || typeof (urlParams) == 'number') { options.url += urlParams; } if(options.url.indexOf(’?’) > -1){ options.url += ’&_=’ + (new Date()).getTime(); }else{ options.url += ’?_=’ + (new Date()).getTime(); } // 分發(fā)顯示加載樣式任務(wù) this.$store.dispatch(’show_loading’); if (tokenFlag !== true) { //如果你們的后臺(tái)不會(huì)接受headers里面的參數(shù),打開這個(gè)注釋,即實(shí)現(xiàn)token通過普通參數(shù)方式傳 // data.token = this.$store.state.user.userinfo.token; options.headers.token = this.$store.state.user.userinfo.token; } //擴(kuò)展Promise使支持finally(),用了babel就不用手寫了^.^ // Promise.prototype.finally=function(callback){ // let Promise = this.constructor; // return this.then( // value => Promise.resolve(callback()).then(() => value), // reason => Promise.resolve(callback()).then(() => { throw reason }) // ); // }; //發(fā)送請(qǐng)求 return new Promise((resolve, reject)=>{ Vue.axios(options).then((res) => { this.$store.dispatch(’hide_loading’); if (res.data[gbs.api_status_key_field] === gbs.api_status_value_field || (res.status === gbs.api_status_value_field && !res.data[gbs.api_status_key_field])) { fn(res.data); } else { if (gbs.api_custom[res.data[gbs.api_status_key_field]]) { gbs.api_custom[res.data[gbs.api_status_key_field]].call(this, res.data); } else { cbs.statusError.call(this, res.data); if (errFn) { errFn.call(this, res.data); } } } resolve(res.data); }).catch((err) => { if(err.response && err.response.status !== 403){ try{ errFn?errFn.call(this, this.$$lib__.isObject(err.response.data) ? err.response.data : {}):null; }catch(err){ console.error(err.message); } } if(err.response && err.response.data === ’’){ cbs.statusError.call(this, {status: err.response.status}); } else if (err.response && this.$$lib__.isObject(err.response.data)) { cbs.statusError.call(this, err.response.data); }else if(err.response){ cbs.requestError.call(this, err); } else { console.error(’Error from ’, ’'’+path+’'.’, err.message); } reject(err); }); }); } else { this.$alert(’您沒有權(quán)限請(qǐng)求該接口!’, ’請(qǐng)求錯(cuò)誤’, { confirmButtonText: ’確定’, type: ’warning’ }); }};
核心代碼為cancelToken參數(shù)
var options = { method: type, url: path, params: params, headers: headers && typeof headers === ’object’ ? headers : {}, cancelToken: new axios.CancelToken(function (cancel) { Vue.Cancel && Vue.Cancel.push(cancel) }) };
補(bǔ)充知識(shí):problem:vue組件局部刷新,在組件銷毀(destroyed)時(shí)取消刷新無效問題
場(chǎng)景:
一個(gè)群發(fā)消息列表(數(shù)組)
列表下有多條消息(元素)
每條正在發(fā)送的消息數(shù)據(jù)狀態(tài)需要實(shí)時(shí)刷新,發(fā)送完成時(shí)需要顯示成功提示符合且不需要刷新,然后3秒消失。首次顯示列表時(shí),已經(jīng)成功的狀態(tài)不顯示這個(gè)成功提示符。
1、定位確定采用局部刷新
2、進(jìn)入消息列表請(qǐng)求獲取列表數(shù)據(jù)的接口,完成發(fā)送的消息不需顯示完成狀態(tài)
3、正在發(fā)送的消息首次渲染時(shí)就調(diào)用setTimeout輪詢刷新當(dāng)前消息的接口,完成時(shí),顯示完成狀態(tài)(新增一個(gè)完成狀態(tài)的字段)
4、頁(yè)面銷毀時(shí),還在發(fā)送的消息也取消刷新
誤區(qū):
1、每條消息沒有抽成一個(gè)單獨(dú)的組件,想要首次渲染組件調(diào)用刷新接口時(shí),只能通過定義全局map變量來映射每條消息的刷新接口的定時(shí)器,明顯增加業(yè)務(wù)開發(fā)的復(fù)雜度,增加了一些不確定性的bug風(fēng)險(xiǎn)。
每條消息抽成組件之后,就可以在組件中的mounted中去調(diào)用刷新的接口,頁(yè)面銷毀時(shí)取消刷新可以在destroyed里面去銷毀。
2、這里的一個(gè)誤區(qū)是在destroyed里面去清除定時(shí)器的id,導(dǎo)致調(diào)用了destroyed鉤子刷新的定時(shí)器還是無法清除。將定時(shí)器id當(dāng)做一個(gè)屬性值存在了每條數(shù)據(jù)所屬的對(duì)象中,然后在子組件(每條消息所屬的)中的destroyed中去讀取該對(duì)象的當(dāng)前的定時(shí)器屬性,因?yàn)樽x出來是undifined,其實(shí)并沒有拿到當(dāng)前消息正在執(zhí)行的定時(shí)器,所以清除不掉。
組件使用有誤,每一個(gè)組件都是一個(gè)獨(dú)立的元素,其中定義的變量也是私有的,定時(shí)器id定在當(dāng)前組件的data中就可以了,不需要再在數(shù)組中的每一條消息中定一個(gè)專屬的定時(shí)器id。
抽象出來的簡(jiǎn)單版刷新數(shù)據(jù),5秒后取消刷新。
let intervalId = nullfunction init() { this.refresh()}function refresh() { intervalId = setTimeout(() => { this.getRefreshData() }, 2000);}function getRefreshData() { console.log(’start get data.....’, intervalId) setTimeout(() => { console.log(’get data.....’) this.refresh() }, 100); }function stopRefresh() { console.log(’stop....’, intervalId) clearInterval(intervalId)}this.init()setTimeout(() => { this.stopRefresh()}, 5000);
以上這篇vue路由切換時(shí)取消之前的所有請(qǐng)求操作就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持好吧啦網(wǎng)。
相關(guān)文章:
1. ajax請(qǐng)求添加自定義header參數(shù)代碼2. ASP基礎(chǔ)知識(shí)VBScript基本元素講解3. 解決android studio引用遠(yuǎn)程倉(cāng)庫(kù)下載慢(JCenter下載慢)4. Kotlin + Flow 實(shí)現(xiàn)Android 應(yīng)用初始化任務(wù)啟動(dòng)庫(kù)5. Python requests庫(kù)參數(shù)提交的注意事項(xiàng)總結(jié)6. Gitlab CI-CD自動(dòng)化部署SpringBoot項(xiàng)目的方法步驟7. 利用CSS3新特性創(chuàng)建透明邊框三角8. 淺談SpringMVC jsp前臺(tái)獲取參數(shù)的方式 EL表達(dá)式9. axios和ajax的區(qū)別點(diǎn)總結(jié)10. python操作mysql、excel、pdf的示例
