vue+elementUI+axios實現的全局loading加載動畫

在請求較多的應用中,loading是必不可少的,否則人們不是認爲程序卡了就是認爲設備卡了

普通的項目中,每次請求基本都要手動寫一下loading的出現和消失,且不說有些麻煩,而且在ajax異步的情況下,如果做不好loading同步,經常會出現loading不出現的情況,而且不同瀏覽器兼容性較差。

一.概念

在vue項目中,有了統一配置機制,可以實現對loading的配置使每次請求前自動出現loading,請求後loading消失

順表一提,本來ajax調爲同步模式挺好用的,但axios沒有同步功能

關於elementui的loading,教程在這裏:https://element.eleme.cn/2.0/#/zh-CN/component/loading

第一種方法是在需要出現loading的地方加v-loading指令,此方法在小應用中可以用,在大型應用中顯得過於繁瑣

第二種是服務方式:

最後一句話是重點,也就是說如果頁面有多個請求一起請求,如果都使用一個服務loading,很可能會出現較快結束請求的那個直接把loading關了,而請求時間長的還沒有結束請求。這點在下面設計的時候需要關注

二.實現

在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,這樣之後可在每個組件的methods中調用$axios命令完成數據請求
Vue.prototype.$axios=axios
// 安裝各類插件
Vue.use(elementui)

let loading;
//內存中正在請求的數量
let loadingNum=0;
function startLoading() {    
	if(loadingNum==0){
		loading = Loading.service({
		  lock: true,
		  text: '拼命加載中...',
		  background:'rgba(255,255,255,0.5)',
		})
	}
	//請求數量加1
	loadingNum++;
}
function endLoading() {
    //請求數量減1
	loadingNum--
	if(loadingNum<=0){
		loading.close()
	}
}

//請求數據攔截器
axios.interceptors.request.use(request => {
  startLoading();
  return request
}, err => {
  return Promise.reject(err);
});


//接收響應攔截器
axios.interceptors.response.use(response => {
  endLoading();
  return response
}, err => {
  endLoading();
  if (err && err.response) {
    switch (err.response.status) {
      case 400: err.message = '請求錯誤(400)'; break;
      case 401: this.$router.push('/login'); break;
      case 403: err.message = '拒絕訪問(403)'; break;
      case 404: err.message = '請求出錯(404)'; break;
      case 408: err.message = '請求超時(408)'; break;
      case 500: err.message = '服務器錯誤(500)'; break;
      case 501: err.message = '服務未實現(501)'; break;
      case 502: err.message = '網絡錯誤(502)'; break;
      case 503: err.message = '服務不可用(503)'; break;
      case 504: err.message = '網絡超時(504)'; break;
      case 505: err.message = 'HTTP版本不受支持(505)'; break;
      default: err.message = `連接出錯(${err.response.status})!`;
    }
  } else {
    err.message = '連接服務器失敗!'
  }
  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()
  } 
})

因爲loading只是一個實例,所以需要加入了請求個數控制,每次請求開始加一個,請求結束減一個,當請求個數爲0時才使loading消失。

這樣配置後應用中其他組件每次調用axios請求都會自動出現消失loading。

三.解決自定義樣式問題

到這裏,每次請求的loading樣式都一模一樣了,如果有的請求需要其他的loading樣式怎麼辦呢?

利用服務中loading只有一個實例的原理,只需要在請求之前就創建出一個loading實例,因爲創建一個實例後再調用會繼續使用這個實例,loading的名字就變了

例:

在每個需要變樣式的請求前面加上這個即可

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章