这里我使用的是以服务方式引入的Loading,参考网上给的全局配置文件,整理了一下。在使用过程中发现了一些问题。

在vue项目文件夹中,这里我就在utils中创建了一个loading.js文件,用来写全局配置:

以服务的方式调用的全屏 Loading 是单例的:若在前一个全屏 Loading 关闭前再次调用全屏 Loading,并不会创建一个新的Loading 实例,而是返回现有全屏 Loading 的实例

所以,下面设置了一个needLoadingRequestCount 变量来记录创建Loading实例的个数,只有当实例个数为0时才会去关闭或开启另一个实例。

import { Loading } from 'element-ui'

let needLoadingRequestCount = 0
let loading

function startLoading() {
  loading = Loading.service({
    target: document.querySelector('.content-loading'),
    lock: true,
    text: '拼命加载中...',
    background: 'rgba(0, 0, 0, 0.8)',
    spinner: 'el-icon-loading'
  })
}

function endLoading() {
  // 指定target后,每次返回的都是单独的实例,所以要在调用新的loading之前检测是否有实例存在,如果有择用close方法
  loading && loading.close()
}

export function showFullScreenLoading() {
  if (needLoadingRequestCount === 0) {
    startLoading()
  }
  needLoadingRequestCount++
}

export function tryHideFullScreenLoading() {
  if (needLoadingRequestCount <= 0) return
  needLoadingRequestCount--
  if (needLoadingRequestCount === 0) {
    endLoading()
  }
}

在使用时,只需要在axios文件中为请求添加一个showLoading请求头:

import axios from 'axios'
import { showFullScreenLoading, tryHideFullScreenLoading } from 'utils/loading'
// import Qs from 'qs'
// import store from '@/store'

axios.defaults.withCredentials = true
var instance = axios.create({
  // 默认方法设置
  method: 'POST',
  // xhrFields: { withCredentials: true },
  //返回数据的格式
  //其可选项是arraybuffer,blob,document,json,text,stream
  responseType: 'json',
  xsrfCookieName: 'XSRF-TOKEN',
  // 返回数据设置,有data和headers两个参数
  transformRequest: [
    function(data) {
      // TODO处理请求参数
      // data = Qs.stringify(data)
      return data
    }
  ],
  headers: {
    'Content-Type': 'application/json;charset=UTF-8'
  },
  // 请求超时设置
  timeout: 30000,
  showLoading: true
})

然后在请求拦截器中,根据请求头的showLoading判断是否需要调用Loading

// response处理
instance.interceptors.response.use(
  response => {
    if (response.config.showLoading) {
      tryHideFullScreenLoading()
    }
    console.log('response-------', response)
    return response.data
  },
  error => {
    tryHideFullScreenLoading()
    return Promise.reject(error)
  }
)
instance.interceptors.request.use(
  config => {
    console.log('config', config)
    if (config.showLoading) {
      showFullScreenLoading()
    }
    return config
  },
  error => {
    console.log(error)
    return Promise.reject(error)
  }
)

上面步骤就可以在请求时,调用Loading页面。下面记录一下常见问题:

1. Loading.service中全局设置时target要加选择器符号
2. 在分页跳转请求时不出现Loading的原因:

场景是这样的:第一次进入页面,Loading正常加载,然后我滑动到页面的最下方。点击下一页,由于我这里下一页是需要发送请求的。所以正常情况根据配置的Loading,这时会出现Loading页面,但是我这里却没有显示。

经过排查,发现是target这里的问题,但target在其他场景都使用正常;说明是跟target目标值有关。这时就想到,是不是我在滑动到页面最下方时,target所指的节点肯定定位不对,要不脱离文档流,要不不存在。因此,我给target指定节点设置了position:relative后,问题就解决了。

Logo

前往低代码交流专区

更多推荐