• elementUI全局loading单例模式


    前面写过一次loading组件的js组件使用:

    ### 封装Loading组件-JS组

    elementUI提供了loading组件的简便使用:

    1、在table等组件上绑定指令:v-loading="loading",然后通过控制变量loading的值为true或false,切换显示和隐藏

    <el-table v-loading="loading">

    2、在使用指令的基础上,自定义加载文案、图标和背景色:

    <el-table
        v-loading="loading"
        element-loading-text="拼命加载中"
        element-loading-spinner="el-icon-loading"
        element-loading-background="rgba(0, 0, 0, 0.8)"
        :data="tableData">

    3、以上都是给单个的组件添加loading条,如果要给整页进行加载:fullscreen修饰符将遮罩插入到body上,lock修饰符锁定屏幕滚动

    <el-button v-loading.fullscreen.lock="fullscreenLoading">指令方式</el-button>

    4、整页加载可以使用服务的方式,遮罩默认为全屏,不需要额外设置修饰符fullscreen:

    <el-button @click="handleClick">服务方式</el-button>
          handleClick() {
            const loading = this.$loading({
              lock: true,
              text: 'Loading',
              spinner: 'el-icon-loading',
              background: 'rgba(0, 0, 0, 0.7)'
            });
            setTimeout(() => {
              loading.close();
            }, 2000);
          }

    5、配合axios做全局的设置:

    实际项目中发现,如果某个页面请求多个接口,且每个接口都返回很慢的话,实际看到的效果是虽然Loading会出现,但是当第一个接口返回值以后后面的Loading都不会出现了,就会出现页面数据从无到有的过滤,用户体验较差。

    原来,是因为elementUI的全屏Loading是单例的:如果前一个Loading关闭之前再次调用了下一个Loading并不会创建一个新的实例,返回的仍然是当前这个Loading实例;同理,当调用任意一个close()方法都会关闭这个Loading实例。因为这几个接口都是同一时间请求的,也就是说当前页面几个Loading实例其实都是同一个,所以关闭后也就都关闭了。

    import axios from 'axios'
    import { Message, Loading } from 'element-ui'
    let instance = axios.create({
      baseURL: '',
      timeout: 60000
    })
    /* 当页面有两个接口时,第一个接口loading的close事件会直接将第二个接口的loading实例也close */
    let loadingInstance = null
    function startLoading () {
      loadingInstance = Loading.service({
        fullscreen: true,
        text: '拼命加载中...',
        background: 'rgba(0, 0, 0, 0.8)'
      })
    }
    function endLoading () {
      loadingInstance.close()
    }
    let needLoadingRequestCount = 0
    function showFullScreenLoading () {
      if (needLoadingRequestCount === 0) {
        startLoading()
      }
      needLoadingRequestCount++
    }
    function tryHideFullScreenLoading () {
      if (needLoadingRequestCount <= 0) return
      needLoadingRequestCount--
      if (needLoadingRequestCount === 0) {
        endLoading()
      }
    }
    // 请求拦截
    instance.interceptors.request.use((config) => {
      showFullScreenLoading()
      return config
    }, (error) => {
      tryHideFullScreenLoading()
      Message.error({message: '请求超时!'})
      return Promise.reject(error)
    })
    // 响应拦截
    instance.interceptors.response.use((response) => {
      tryHideFullScreenLoading()
      if (response.data && response.data.code && response.data.code === 200) {
        return response.data
      } else {
        Message({
          message: response.data.msg || '接口错误',
          type: 'error'
        })
      }
    }, (error) => {
      tryHideFullScreenLoading()
      return Promise.reject(error)
    })
    export default instance

    每次创建Loading实例的时候判断当前是否存在,如果当前还没有Loading实例就创建一个,如果有就不会再创建而是计数;每次关闭的时候判断当前的计数,如果是0了就关闭,否则也计数减一,直到为0的时候表示当前所有页面所有接口都返回结束了,此时执行关闭Loading.close()操作关闭菊花。

    service()中没有参数对象时,

    有参数对象时,

      loadingInstance = Loading.service({
        fullscreen: true,
        text: '拼命加载中...',
        background: 'rgba(0, 0, 0, 0.8)'
      })

  • 相关阅读:
    The prefix "mvc" for element "mvc:annotation-driven" is not bound 的解决方法
    Intellij Idea14 jstl标签的引入
    17个短视频渠道分成收益全解析
    chrome浏览器插件推荐——Vimium 篇
    从Java代码到字节码(1)
    Java跳出循环-break和continue语句
    Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
    Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.5:test
    XML文件解析
    jpa基于按annotation的hibernate主键生成策略
  • 原文地址:https://www.cnblogs.com/wuqilang/p/13166393.html
Copyright © 2020-2023  润新知