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
作用
制作頁面加載時動態頁面,在頁面頂端提供動態進度條,表明當前頁面正在加載狀態。

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