react + axios请求拦截实现全局loading组件

在我们的后台管理系统开发过程中,我们经常有这样一种需求, 比如在请求一个接口的时候打开loading加载,然后在请求成功之后关闭loading。这样每个请求都需要写着两句,这样写起来实在繁琐,下文实现了一个全局的loading,只要有请求就会有loading状态打开和关闭的操作。二话不多说上代码。实现思路::
实现一个计数的全局类,在请求之前计数加一,成功后计数减一,订阅这个状态的变化,控制loading组件的加载

import axios form  'axios';
import { Spin } from 'antd';
class Loading {
   constructor () {
       this.loadingTag = 0;
       this.subscriptions = [];
   }
   add () {
       this.loadingTag++;
       this.subscriptions.forEach(f => f(this.loadingTag));
   }
   sub () {
       this.loadingTag--;
       this.subscriptions.forEach(f => f(this.loadingTag));
   }
   get () {
       return this.loadingTag;
   }
   subscribe (f) {
       this.subscriptions.push(f);
   }
}
let loadingPublisher = new Loading();
// 对请求进行拦截, 请求之前加一,成功后减一
axios.interceptors.request.use(
     res => {
     	 // 可以添加参数控制是否需要loading状态
         if (res && !res.ignoreLoading) {
             loadingPublisher.add();
         }
         return res;
      }, error => {
          return Promise.reject(error);
      }
);
axios.interceptors.response.use(
     response => {
     	// 可以添加参数控制是否需要loading状态
         if (response && response.config && !response.config.ignoreLoading) {
             loadingPublisher.sub();
         } else {
             return response;
         }
      },
      error => {
          loadingPublisher.sub();
          return Promise.reject(error.response); // 返回接口返回的错误信息
      }
);
//实现loading组件
class YMLoading extends Component {
   constructor (props) {
       super(props);
       this.state = {
           globalLoading: false
       };
   }
   componentDidMount () {
       // 增加订阅loading状态更新
       loadingPublisher.subscribe((loadingTag)=>{
           if (this.state.globalLoading !== !!loadingTag) {
               this.setState({globalLoading: !!loadingTag});
           }
       });
   }
   render () {
       return <Spin spinning={this.state.globalLoading} tip= '加载中...' indicator={<img className='loading_spin' src={require('@imgs/loading.png')}/>}/>;
   }
}

class App extends Component {
   	render () {
   		return <YMLoading />
   	}
}

至此代码全部实现,代码复制即用,用兴趣的同学可以试试用vue也实现一个,一起讨论下。

发布了6 篇原创文章 · 获赞 21 · 访问量 3243

猜你喜欢

转载自blog.csdn.net/m0_37685031/article/details/105457438