Vue封装Axios结合Element UI实现全局的loading显示效果

发布于 2020-03-17  1017 次阅读


vue实现请求数据显示loading效果

Axios封装

使用前请下载好element-ui 和 axios

import axios from 'axios';
import { Message, Loading } from 'element-ui';
import _ from 'lodash';

const http = axios.create({
  baseURL: '', //设置请求的base url
  timeout: 50000 //超时时长
});

//loading对象
let loading = null;

//当前正在请求的数量
let needLoadingRequestCount = 0;

//显示loading
function showLoading(target) {
  // 后面这个判断很重要,因为关闭时加了抖动,此时loading对象可能还存在,
  // 但needLoadingRequestCount已经变成0.避免这种情况下会重新创建个loading
  if (needLoadingRequestCount === 0 && !loading) {
    loading = Loading.service({
      lock: true,
      text: "Loading...",
      spinner: 'el-icon-loading',
      background: 'rgba(255, 255, 255, 0.5)',
      target: target || "body"
    });
  }
  needLoadingRequestCount++;
}

//隐藏loading
function hideLoading() {
  needLoadingRequestCount--;
  needLoadingRequestCount = Math.max(needLoadingRequestCount, 0); //做个保护
  if (needLoadingRequestCount === 0) {
    //关闭loading
    toHideLoading();
  }
}

//防抖:将 300ms 间隔内的关闭 loading 便合并为一次。防止连续请求时, loading闪烁的问题。
var toHideLoading = _.debounce(() => {
  loading.close();
  loading = null;
}, 300);

//添加请求拦截器
http.interceptors.request.use(config => {
  //判断当前请求是否设置了不显示Loading
  if (config.params.showLoading !== false) {
    showLoading(config.params.loadingTarget);
  }
  return config;
}, err => {
  //判断当前请求是否设置了不显示Loading
  if (err.params.showLoading !== false) {
    hideLoading();
  }
  Message.error('请求超时!');
  return Promise.resolve(err);
});

//响应拦截器
http.interceptors.response.use(
  response => {
    //判断当前请求是否设置了不显示Loading(不显示自然无需隐藏)
    if (response.config.params.showLoading !== false) {
      hideLoading();
    }
    return response;
  },
  error => {
    //判断当前请求是否设置了不显示Loading(不显示自然无需隐藏)
    if (error.config.params.showLoading !== false) {
      hideLoading();
    }
    if (error.response && error.response.data && error.response.data.message) {
      var jsonObj = JSON.parse(error.response.data.message);
      Message.error(jsonObj.message);
    } else {
      Message.error(error.message);
    }
    return Promise.reject(error);
  }
);

export default http;

main.js中引入

main.js 中将该组件引入,并定义成原型属性方便使用。

import http from '';//封装axios的文件路径
Vue.prototype.axios = http;

使用

在请求 params 中传递个 showLoading:false 参数,则该请求不会有 loading 效果 , 反之亦然

this.axios.get('请求', {params: {'showLoading': false}}).then(res => {
      console.log(res)
 })

如果将请求 header 中 loadingTarget 设置为页面上某个元素的选择符,则 loading 效果会只显示在个元素区域上。

this.axios.get('请求', {params: {'loadingTarget': '#app'}}).then(res => {
      console.log(res)
})

如果没有loading效果只有文字请检查是否以正确配置element-ui

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.use(ElementUI);

原文 出自 并在此基础上做了一些改动以便当前版本可以正常使用


I struggle for what I love, so I can be happy here.