zoukankan      html  css  js  c++  java
  • Element-ui实现loading的局部刷新

    后台管理系统loading的局部刷新

    在一次vue+element-ui后台管理系统的项目中,遇到这样一个问题,引入element-ui加载框后,loading会占满整个屏幕,虽然通过改变路由实现了局部刷新,但是loading的全屏刷新,让人看上去很是不爽,以为是全局刷新。再一个问题就是,一个页面中可能含有的多个请求,在拦截器汇总设置关闭loading后,会出现的问题就是,有些数据还是空的,但是loading框就已经关闭了我们需要实现的是所有请求完成后关闭loading。所以这是另一个问题。 

    所以为了解决这两个问题做此总结,帮助更多的小伙伴脱坑。
    如果要实现全局的刷新则可以查看博主的另一片总结:传送门
     
    没有思路就没有出路,先说思路:
     
    局部的loading框的出现,element-ui在vue中引入后,就会默认在vue原型链上挂在一个loaiding方法,可以通过vue.prototype.$loading看到,解决问题的关键就在这个方法中,该方法中可以设置这么几个属性lock,text,target,background,我们搞清楚这些,问个问题也就迎刃而解。lock可以看作是loading的开关,text则是loading的文本的提示信息。target则是根据类型显示需要出现loading的区域。background则是loading的bgcolor
     
    所有请求完成后再关闭loading,默认大家都知道vue拦截器。解决思路比较简单,创建一个定时器,在request时,num++,在response时num--当num<=0时,则所有请求都有了结果,这个时候我们就可以关闭loading了。 

    情景及Demo

    后台管理系统,header,aside,main,除了loading,404外,实现main的局部刷新,且所有请求完成后再关闭loading框。 先看我们的网络请求层,封装的fetch.js文件. 
    import axios                from 'axios'
    import { Message} from 'element-ui'
    import router               from '../router/permission'
    import Vue from 'vue'
     
    // loading框设置局部刷新,且所有请求完成后关闭loading框
    let loading;
    function startLoading() {
      loading = Vue.prototype.$loading({
        lock: true,
        text: "Loading...",
        target: document.querySelector('.loading-area')//设置加载动画区域
      });
    }
    function endLoading() {
      loading.close();
    }
     
    //声明一个对象用于存储请求个数
    let needLoadingRequestCount = 0;
    function showFullScreenLoading() {
        if (needLoadingRequestCount === 0) {
            startLoading();
        }
        needLoadingRequestCount++;
    };
    function tryHideFullScreenLoading() {
        if (needLoadingRequestCount <= 0) return;
        needLoadingRequestCount--;
        if (needLoadingRequestCount === 0) {
          endLoading();
        }
    };
     
    //  请求拦截
    axios.interceptors.request.use(config => {
      showFullScreenLoading();
      return config;
    }, err => {
      tryHideFullScreenLoading();
      Message.error({ message: '请求超时!' });
      return Promise.resolve(err);
    })
    //  响应拦截
    axios.interceptors.response.use(res => {
      tryHideFullScreenLoading();
      if (res.data.code == 200) {
        return res.data.result;
      } else if (res.data.code == 401) {
        router.push('/login');
        return Promise.reject(res);
      } else if (res.data.code == 201) {
        Message.error({ message: res.data.msg });
        return Promise.reject(res);
      }
      return Promise.reject(res);
    }, err => {
      tryHideFullScreenLoading();
      if (err.response.status == 504 || err.response.status == 404) {
        Message.error({ message: '服务器被吃了⊙﹏⊙∥' });
      } else if (err.response.status == 403) {
        Message.error({ message: '权限不足,请联系管理员!' });
      } else {
        Message.error({ message: '未知错误' });
      }
      return Promise.reject(err);
    })
     
    let base = '';
    export const postRequest = (url, params) => {
      return axios({
        method: 'post',
        url: `${base}${url}`,
        data: params,
        transformRequest: [function (data) {
          let ret = ''
          for (let it in data) {
            ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
          }
          return ret
        }],
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      });
    }
    export const getRequest = (url, data = '') => {
      return axios({
        method: 'get',
        params: data,
        url: `${base}${url}`
      });
    }
    下来我们就需要查看我们的主入口文件Home.vue. 
     
    <template>
    <!-- 布局 -->
      <el-container>
        <el-header class="header-wraper" >
          <admin-header></admin-header>
        </el-header>
        <el-container class="container">
          <el-aside >
            <admin-aside></admin-aside>
          </el-aside>
          <el-main class="loading-area">
            <keep-alive>
             <router-view v-if="this.$route.meta.keepAlive"></router-view>
            </keep-alive>
            <router-view v-if="!this.$route.meta.keepAlive"></router-view>
          </el-main>
        </el-container>
      </el-container>
    </template>
     
    <script>
    import AdminAside  from '@/components/Commons/Aside/index';
    import AdminHeader from '@/components/Commons/Header/index'
        export default {
        components: {
          AdminAside,
          AdminHeader
        },
        data () {
          return {}
        },
      }
    </script>
     
    <style lang="less" scoped>
      .header-wraper {
        width: 100%;
        height: 70px;
        border-bottom: 1px solid #ccc;
        overflow: hidden;
      }
      .container {
        width: 100%;
        height: 100%;
      }
    </style>
    关键实现以上两部就可实现头部预览效果局部刷新。
  • 相关阅读:
    浏览器是怎样工作的二:渲染引擎 HTML解析(1)(转)
    凯文.都迪的超级记忆力训练教程
    程序员的修炼之道
    我编程我快乐——程序员的职业规划
    SQL Server 数据库备份和还原认识和总结(一)
    SQL Server 管理数据收集
    汇总SQL Server里的相关运算符、子句、谓词等
    SQL Server 数据库备份和还原认识和总结(二)
    解决报表控件报CS0433错误
    通过笔记本配件,理解抽象类接口和委托事件
  • 原文地址:https://www.cnblogs.com/bgwhite/p/9869886.html
Copyright © 2011-2022 走看看