1.问题:
开发项目时需要在接口等待期间调用一个Loading组件提示组件提示用户操作已经受理;
最初的解决方案是在每一个调用了接口的页面直接使用 AntdMobile 的活动指示器组件 <ActivityIndicator />,后续开发中发现该方案代码冗余度太高并且属于重复工作,查阅资料后决定在axios拦截器中进行一些处理以实现全局Loading提示组件;
2.解决方案:
使用 ReactDOM、AntdMobile 配合 Axios拦截器 实现一个全局Loading组件,调用接口时自动展示Loading;
React:ReactDOM.render();
AntdMobile:<ActivityIndicator />;https://mobile.ant.design/components/activity-indicator-cn/
axios:interceptors;http://www.axios-js.com/zh-cn/docs/#%E6%8B%A6%E6%88%AA%E5%99%A8
配置axios
axios.js
1 import React from 'react' 2 import { render } from 'react-dom' 3 import axios from 'axios' 4 import { ActivityIndicator, Toast } from 'antd-mobile' 5 import history from '@/utils/history' 6 7 var CancelToken = axios.CancelToken 8 var source = CancelToken.source() 9 let httpRequestCount = 0 10 11 const showLoading = () => { 12 if (httpRequestCount === 0) { 13 const loadingContainer = document.createElement('div') 14 loadingContainer.setAttribute('id', 'axiosLoading') 15 document.body.appendChild(loadingContainer) 16 render(<ActivityIndicator toast text='Loading...' animating />, loadingContainer) 17 } 18 httpRequestCount++ 19 } 20 const hideLoading = () => { 21 httpRequestCount-- 22 if (httpRequestCount === 0) { 23 document.querySelector('body').removeChild(document.querySelector('#axiosLoading')) 24 } 25 } 26 27 axios.source = source 28 29 axios.interceptors.request.use(function (config) { 30 showLoading() 31 return config 32 }, handleError) 33 34 axios.interceptors.response.use(function responseInterceptor (response) { 35 hideLoading() 36 // Do something with response data 37 if (response && response.status === 200 && response.data) { 38 return handleRes(response.data) 39 } 40 if (response && response.status === 999 && response.data) { 41 return handleRes(response.data) 42 } 43 return Promise.reject(response.data && response.data.responseMessage) 44 }, handleError) 45 46 function handleError (error) { 47 hideLoading() 48 history.push('/') 49 return Promise.reject(error) 50 } 51 52 function handleRes (data) { 53 return new Promise((resolve, reject) => { 54 if (data && data.resultCode) { 55 switch (data.resultCode) { 56 case '0': 57 return resolve(data) 58 default: 59 Toast.fail(data.resultDesc) 60 return resolve(data) 61 } 62 } else { 63 return resolve(data) 64 } 65 }) 66 } 67 68 // ...
完成 axios的配置后在使用axios调用接口的等待期间则会吹出现提示信息和动画;
若是需要在某些接口等待期间不进行提示可以在接口调用时增加配置项然后在axios拦截器中进行处理;