dva 中頁面過渡效果封裝的很好饺蚊,下面介紹常用的兩個 js 庫。
之前對 dva-loading 理解存在誤區(qū)亥宿,認為只要在 index.js 中配置一下就沒事了卸勺,事實上 dva-loading 只是提供當前異步加載方法的狀態(tài)(異步加載中狀態(tài)為 true,異步加載完成狀態(tài)為 false)烫扼,對應(yīng)加載樣式由各自組件自己控制曙求,如:Antd 中 Table 組件自身的 loading 屬性。并添加完整流程示例代碼映企。
一悟狱、過渡組件 dva-loading
傳統(tǒng)做法
比如請求一個用戶頁面,剛進去的時候由于要去服務(wù)器請求數(shù)據(jù)需要花費時間堰氓,這段時間頁面應(yīng)該是不能點擊的狀態(tài)挤渐。
如果不使用這個組件,傳統(tǒng)做法是寫個蒙版組件双絮,提供兩個方法 start() 和 end()浴麻,當進行 ajax 請求開始時調(diào)用 start() 方法給整個頁面加上一層蒙版,此時不能進行操作囤攀,在請求結(jié)束也就是 ajax 的 success 回調(diào)函數(shù)中調(diào)用 end() 方法關(guān)閉蒙版软免,表明數(shù)據(jù)已經(jīng)請求到了,可以操作頁面焚挠。
作用
該組件僅僅監(jiān)聽異步加載狀態(tài)膏萧,這從它的調(diào)用方式就可以看出來 const isLoading = loading.effects['user/query']
,其中 user/query
是 model 中的異步請求方法蝌衔。
loading 在異步請求發(fā)出那一刻會持續(xù)監(jiān)聽該異步請求方法的狀態(tài)榛泛,在異步請求結(jié)束之前 isLoading 的值一直是 true,當此次異步請求結(jié)束時 isLoading 的值變成 false噩斟,同時 loading 對象停止監(jiān)聽曹锨。
配置
dva 項目的 index.js 文件:
import createLoading from 'dva-loading';
const app = dva();
app.use(createLoading());
配置完成后,在任何一個 dva 的 routes 組件中就都會有一個 loading 對象亩冬,如果你對 dva 稍有了解的話艘希,應(yīng)該不難知道它在哪。比如下面這行代碼中的 loading 對象就是由于上面的配置硅急。
export default connect(({ app, loading }) => ({ app, loading }))(App);
打印一下 loading 對象覆享,可看到內(nèi)容如下:
loading: {
global: false,
models: {app: false},
effects: {app: false}
}
loading 有三個方法,其中 loading.effects['user/query']
為監(jiān)聽單一異步請求狀態(tài)营袜,當頁面處于異步加載狀態(tài)時該值為 true撒顿,當頁面加載完成時,自動監(jiān)聽該值為 false荚板。
如果同時發(fā)出若干個異步請求凤壁,需求是當所有異步請求都響應(yīng)才做下一步操作吩屹,可以使用 loading.global()
方法,該方法監(jiān)聽所有異步請求的狀態(tài)拧抖。
怎么用煤搜?
使用 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 請求后臺返回數(shù)據(jù)
const result = axios.request('xxx/xxx');
// 調(diào)用 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 }) => {
/**
根據(jù) loading.effects 對象判斷當前異步加載是否完成,并將該值傳遞給 Table 組件的 loading 屬性掉弛,
Table 組件會自己控制加載樣式症见。dva-loading 在這里的作用只是提供異步加載的狀態(tài),
具體加載樣式由對應(yīng)組件自己提供殃饿。
*/
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
作用
制作頁面加載時動態(tài)頁面,在頁面頂端提供動態(tài)進度條业栅,表明當前頁面正在加載狀態(tài)秒咐。
用法
xx.js 中
import NProgress from 'nprogress';
提供了兩個方法:NProgress.start() 和 NProgress.done()。
在剛開始請求(可以認為是 ajax 請求)頁面數(shù)據(jù)時調(diào)用 NProgress.start() 方法碘裕,此時頁面頂端會有藍色動態(tài)進度條携取;在頁面請求數(shù)據(jù)完畢時(可以認為是 ajax 的 success 回調(diào)函數(shù)),調(diào)用 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 不一致時說明進行了頁面跳轉(zhuǎn)
NProgress.start(); // 頁面開始加載時調(diào)用 start 方法
if (!loading.global) { // loading.global 為 false 時表示加載完畢
NProgress.done(); // 頁面請求完畢時調(diào)用 done 方法
currHref = href; // 將新頁面的 href 值賦值給 currHref
}
}
}
export default withRouter(connect(({ app, loading }) => ({ app, loading }))(App));