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));

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM