在請(qǐng)求較多的應(yīng)用中,loading是必不可少的,否則人們不是認(rèn)為程序卡了就是認(rèn)為設(shè)備卡了
普通的項(xiàng)目中锈至,每次請(qǐng)求基本都要手動(dòng)寫一下loading的出現(xiàn)和消失,且不說有些麻煩译秦,而且在ajax異步的情況下峡捡,如果做不好loading同步,經(jīng)常會(huì)出現(xiàn)loading不出現(xiàn)的情況诀浪,而且不同瀏覽器兼容性較差棋返。
一.概念
在vue項(xiàng)目中,有了統(tǒng)一配置機(jī)制雷猪,可以實(shí)現(xiàn)對(duì)loading的配置使每次請(qǐng)求前自動(dòng)出現(xiàn)loading,請(qǐng)求后loading消失
順帶一提晰房,本來ajax調(diào)為同步模式挺好用的求摇,但axios沒有同步功能
關(guān)于elementui的loading,教程在這里:https://element.eleme.cn/2.0/#/zh-CN/component/loading
第一種方法是在需要出現(xiàn)loading的地方加著
v-loading
指令殊者,此方法在小應(yīng)用中可以用与境,在大型應(yīng)用中顯得過于繁瑣第二種是服務(wù)方式:
最后一句話是重點(diǎn),也就是說如果頁面有多個(gè)請(qǐng)求一起請(qǐng)求猖吴,如果都使用一個(gè)服務(wù)loading摔刁,很可能會(huì)出現(xiàn)較快結(jié)束請(qǐng)求的那個(gè)直接把loading關(guān)了,而請(qǐng)求時(shí)間長(zhǎng)的還沒有結(jié)束請(qǐng)求海蔽。這點(diǎn)在下面設(shè)計(jì)的時(shí)候需要關(guān)注
二.實(shí)現(xiàn)
在main.js中共屈,引入vue,axios,elementui
import Vue from 'vue'
import App from './App'
import router from './router'
import elementui from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import axios from 'axios'
import {Loading} from 'element-ui'
//修改原型鏈,全局使用axios,這樣之后可在每個(gè)組件的methods中調(diào)用$axios命令完成數(shù)據(jù)請(qǐng)求
Vue.prototype.$axios=axios
// 安裝各類插件
Vue.use(elementui)
let loading;
//內(nèi)存中正在請(qǐng)求的數(shù)量
let loadingNum=0;
function startLoading() {
if(loadingNum==0){
loading = Loading.service({
lock: true,
text: '拼命加載中...',
background:'rgba(255,255,255,0.5)',
})
}
//請(qǐng)求數(shù)量加1
loadingNum++;
}
function endLoading() {
//請(qǐng)求數(shù)量減1
loadingNum--
if(loadingNum<=0){
loading.close()
}
}
//請(qǐng)求數(shù)據(jù)攔截器
axios.interceptors.request.use(request => {
startLoading();
return request
}, err => {
return Promise.reject(err);
});
//接收響應(yīng)攔截器
axios.interceptors.response.use(response => {
endLoading();
return response
}, err => {
endLoading();
if (err && err.response) {
switch (err.response.status) {
case 400: err.message = '請(qǐng)求錯(cuò)誤(400)'; break;
case 401: this.$router.push('/login'); break;
case 403: err.message = '拒絕訪問(403)'; break;
case 404: err.message = '請(qǐng)求出錯(cuò)(404)'; break;
case 408: err.message = '請(qǐng)求超時(shí)(408)'; break;
case 500: err.message = '服務(wù)器錯(cuò)誤(500)'; break;
case 501: err.message = '服務(wù)未實(shí)現(xiàn)(501)'; break;
case 502: err.message = '網(wǎng)絡(luò)錯(cuò)誤(502)'; break;
case 503: err.message = '服務(wù)不可用(503)'; break;
case 504: err.message = '網(wǎng)絡(luò)超時(shí)(504)'; break;
case 505: err.message = 'HTTP版本不受支持(505)'; break;
default: err.message = `連接出錯(cuò)(${err.response.status})!`;
}
} else {
err.message = '連接服務(wù)器失敗!'
}
message.error(err.message);
return Promise.reject(err);
});
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
template: '<App/>',
components: { App },
data: {
eventHub: new Vue()
}
})
因?yàn)閘oading只是一個(gè)實(shí)例党窜,所以需要加入了請(qǐng)求個(gè)數(shù)控制拗引,每次請(qǐng)求開始加一個(gè),請(qǐng)求結(jié)束減一個(gè)幌衣,當(dāng)請(qǐng)求個(gè)數(shù)為0時(shí)才使loading消失矾削。
這樣配置后應(yīng)用中其他組件每次調(diào)用axios請(qǐng)求都會(huì)自動(dòng)出現(xiàn)消失loading。
三.解決自定義樣式問題
到這里豁护,每次請(qǐng)求的loading樣式都一模一樣了哼凯,如果有的請(qǐng)求需要其他的loading樣式怎么辦呢?
利用服務(wù)中l(wèi)oading只有一個(gè)實(shí)例的原理楚里,只需要在請(qǐng)求之前就創(chuàng)建出一個(gè)loading實(shí)例断部,因?yàn)閯?chuàng)建一個(gè)實(shí)例后再調(diào)用會(huì)繼續(xù)使用這個(gè)實(shí)例,loading的名字就變了
例:
在每個(gè)需要變樣式的請(qǐng)求前面加上這個(gè)即可