zoukankan      html  css  js  c++  java
  • dva-loading 实践用法

    dva 中页面过渡效果封装的很好,下面介绍常用的两个 js 库。

    之前对 dva-loading 理解存在误区,认为只要在 index.js 中配置一下就没事了,事实上 dva-loading 只是提供当前异步加载方法的状态(异步加载中状态为 true,异步加载完成状态为 false),对应加载样式由各自组件自己控制,如:Antd 中 Table 组件自身的 loading 属性。并添加完整流程示例代码。

    一、过渡组件 dva-loading

    传统做法

    比如请求一个用户页面,刚进去的时候由于要去服务器请求数据需要花费时间,这段时间页面应该是不能点击的状态。

    如果不使用这个组件,传统做法是写个蒙版组件,提供两个方法 start() 和 end(),当进行 ajax 请求开始时调用 start() 方法给整个页面加上一层蒙版,此时不能进行操作,在请求结束也就是 ajax 的 success 回调函数中调用 end() 方法关闭蒙版,表明数据已经请求到了,可以操作页面。

    作用

    该组件仅仅监听异步加载状态,这从它的调用方式就可以看出来 const isLoading = loading.effects['user/query'],其中 user/query 是 model 中的异步请求方法。

    loading 在异步请求发出那一刻会持续监听该异步请求方法的状态,在异步请求结束之前 isLoading 的值一直是 true,当此次异步请求结束时 isLoading 的值变成 false,同时 loading 对象停止监听。

    配置

    dva 项目的 index.js 文件:

    import createLoading from 'dva-loading';
    
    const app = dva();
    
    app.use(createLoading());

    配置完成后,在任何一个 dva 的 routes 组件中就都会有一个 loading 对象,如果你对 dva 稍有了解的话,应该不难知道它在哪。比如下面这行代码中的 loading 对象就是由于上面的配置。

    export default connect(({ app, loading }) => ({ app, loading }))(App);

    打印一下 loading 对象,可看到内容如下:

    loading: {
      global: false,
      models: {app: false},
      effects: {app: false}
    }

    loading 有三个方法,其中 loading.effects['user/query'] 为监听单一异步请求状态,当页面处于异步加载状态时该值为 true,当页面加载完成时,自动监听该值为 false。

    如果同时发出若干个异步请求,需求是当所有异步请求都响应才做下一步操作,可以使用 loading.global() 方法,该方法监听所有异步请求的状态。

    怎么用?

    使用 Antd 的 Table 组件 时,查阅 API 可以看到有个 loading 的属性。如果该属性值为 true,Table 组件自身会显示加载效果,该值为 false,加载效果消失。可以通过 loading 对象判断当前是否有异步加载。具体示例代码如下:

    // src > models >user.js
    export default {
      namespace: 'user',
      state: {
        userList: [],      // 存放用户列表
      },
      effects: {
        * query ({ payload = {} }, { call, put }) {
          // 获取用户列表,赋值给 userList
          // 使用 axios 或者 ajax 请求后台返回数据
          const result = axios.request('xxx/xxx');
          // 调用 reducers 中的 updateState 方法改变 state 中 userList 的值
          yield put({ type: 'updateState', payload: { userList: result.data });
        }
      },
      reducers: {
        updateState (state, { payload }) {
          return { ...state, ...payload };
        },
      },
    }
    
    // src > routes > user.js
    import React from 'react';
    import { connect } from 'dva';
    import { Table } from 'antd';
    
    const User = ({ dispatch, user, loading }) => {
      /** 
        根据 loading.effects 对象判断当前异步加载是否完成,并将该值传递给 Table 组件的 loading 属性,
        Table 组件会自己控制加载样式。dva-loading 在这里的作用只是提供异步加载的状态,
        具体加载样式由对应组件自己提供。
      */
      const isLoading = loading.effects['user/query']
      const { userList } = user
    
      return (
        <Table
          dataSource={userList}
          loading={isLoading}
          rowKey={record => record.id}
        />
      );
    }
    
    export default connect(({ user, loading }) => ({ user, loading }))(User);

    注:如果还有疑问,可下方留言。

    二、动画组件 nprogress

    安装

    $ npm install nprogress 

    作用

    制作页面加载时动态页面,在页面顶端提供动态进度条,表明当前页面正在加载状态。

     
    nprogress

    用法

    xx.js 中

    import NProgress from 'nprogress';
    

    提供了两个方法:NProgress.start() 和 NProgress.done()。

    在刚开始请求(可以认为是 ajax 请求)页面数据时调用 NProgress.start() 方法,此时页面顶端会有蓝色动态进度条;在页面请求数据完毕时(可以认为是 ajax 的 success 回调函数),调用 NProgress.done() 方法,此时蓝色进度条会瞬间加载 100% 然后消失。

    三、dva-loading 和 nprogress 配合使用

    index.js 中注册 dva-loading 插件。

    import createLoading from 'dva-loading';
    
    const app = dva();
    
    app.use(createLoading());

    app.js 组件中使用。

    import React from 'react';
    import { connect } from 'dva';
    import NProgress from 'nprogress';
    
    const App= ({ app, loading }) => {
    
        let currHref = '';
        const href = window.location.href;    // 浏览器地址栏中地址
        if (currHref !== href) {  // currHref 和 href 不一致时说明进行了页面跳转
            NProgress.start();    // 页面开始加载时调用 start 方法
            if (!loading.global) {  // loading.global 为 false 时表示加载完毕
                NProgress.done();  // 页面请求完毕时调用 done 方法
                currHref = href;   // 将新页面的 href 值赋值给 currHref
            }
        }
            
    }
    
    export default withRouter(connect(({ app, loading }) => ({ app, loading }))(App));
  • 相关阅读:
    View Focus的处理过程及ViewGroup的mFocused字段分析
    Android按键事件处理流程 -- KeyEvent
    Android中将xml布局文件转化为View树的过程分析(下)-- LayoutInflater源码分析
    Android中将xml布局文件转化为View树的过程分析(上)
    IntentService源码分析
    Android源码分析之SharedPreferences
    进程间传递文件描述符
    Epoll在LT和ET模式下的读写方式
    gdb
    Android开发之漫漫长途 Fragment番外篇——TabLayout+ViewPager+Fragment
  • 原文地址:https://www.cnblogs.com/sexintercourse/p/12098251.html
Copyright © 2011-2022 走看看