一、概述
以清單頁中的标準清單為主
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2Lc1TPB5EerRlT5lleOpHOsJGcohVYsR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2LcRHelR3LcJzLctmch1mclRXY39jM3IjN0QjM0ETOwgDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
Ant Design Pro 預設通過隻需浏覽器單方面就可處理的 HashHistory 來完成路由。如果要切換為 BrowserHistory,那在 src/index.js 中也有對應的内容可以直接修改,但需要在後端伺服器進行相應路由配置。
二、詳述
加載過程圖
2.1、菜單→路由→元件
在左側的導航欄點選 清單頁 > 标準清單 後,可以進入到上面截圖所示的頁面。導航欄的内容在 src/common/menu.js 中【或者服務擷取的位址】
菜單:
{
name: '清單頁',
icon: 'table',
path: 'list',
children: [
{
name: '查詢表格',
path: 'table-list',
},
{
name: '标準清單',
path: 'basic-list',
},
//……
],
},
路由
全局的路由關系是:src/index.js 中通過 app.router(require(‘./router’).default);,将 src/router.js 綁定到 dva 執行個體的 router 方法上。而在 src/router.js 中又引入了 src/common/router.js 中的 getRouterData 作為資料源。
其實就是相當于:src/common/menu.js 中 path 所指向的路徑對應于 src/common/router.js 中的路由記錄。
export const getRouterData = (app) => {
const routerConfig = {
...,
'/list/basic-list': {
component: dynamicWrapper(app, ['list'], () => import('../routes/List/BasicList')),
},
...,
};
...
}
這裡調用了同檔案内的 lazy-loading 的動态加載函數 dynamicWrapper,有 3 個參數,app 為全局 dva 執行個體,models 為一個帶有相關 dva Model 的 Array,component 即為該路由記錄對應的實際元件。
const dynamicWrapper = (app, models, component) => {...};
可以看到:
1、加載路由的時候,會動态加載目前檔案下的model檔案,也就是對應檔案下的src/models/list.js
元件:
src/routes/List/BasicList.js,具體元件。已省略部分代碼
import React, { PureComponent } from 'react';
import { connect } from 'dva';
//……
import PageHeaderLayout from '../../layouts/PageHeaderLayout';
@connect(({ list, loading }) => ({
list,
loading: loading.models.list,
}))
export default class BasicList extends PureComponent {
componentDidMount() {
this.props.dispatch({
type: 'list/fetch',
payload: {
count: ,
},
});
}
render() {
return (
<PageHeaderLayout>{/* 頁面内容…… */}</PageHeaderLayout>
);
}
}
2.2、@connect 裝飾器
元件寫法中調用了 dva 所封裝的 react-redux 的 @connect 裝飾器,用來接收綁定的 list 這個 model 對應的 redux store。注意到這裡的裝飾器實際除了 app.state.list 以外還實際接收 app.state.loading 作為參數,這個 loading 的來源是 src/index.js 中調用的 dva-loading這個插件。
import createLoading from ‘dva-loading’;
app.use(createLoading());
它傳回的資訊包含了 global、model 和 effect 的異步加載完成情況。
資料map一
{
"global": true,
"models": {
"list": false,
"user": true,
"rule": false
},
"effects": {
"list/fetch": false,
"user/fetchCurrent": true,
"rule/fetch": false
}
}
注意到在這裡帶上 {count: 5} 這個 payload 向 store 進行了一個類型為 list/fetch 的 dispatch,在 src/models/list.js 中就可以找到具體的對應操作。
import { queryFakeList } from '../services/api';
export default {
namespace: 'list',
state: {
list: [],
},
effects: {
*fetch({ payload }, { call, put }) {
const response = yield call(queryFakeList, payload);
yield put({
type: 'queryList',
payload: Array.isArray(response) ? response : [],
});
},
/* ... */
},
reducers: {
queryList(state, action) {
return {
...state,
list: action.payload,
};
},
/* ... */
},
};
View中使用
1、 connect使用
@connect(({ list, loading }) => ({
list,//①
loading: loading.models.list,//②
}))
說明:
1、connect 有兩個參數,mapStateToProps以及mapDispatchToProps,一個将狀态綁定到元件的props一個将方法綁定到元件的props
2、代碼①:将實體list中的state資料綁定到props,注意綁定的是實體list整體,使用時需要list.[state中的具體變量]
3、代碼②:通過loading将上文“資料map一”中的models的list的key對應的value讀取出來。指派給loading,以友善使用,如表格是否有加載圖示
當然代碼②也可以通過key value編寫:loading.effects[“list/fetch”]
2、 變量擷取
因,在src/models/list.js
export default {
namespace: 'list',
state: {
list: [],
},
故在view中使用
render() {
const { list: { list }, loading } = this.props;
說明:
定義使用時:list: { list } ,含義實體list下的state類型的list變量
作者:木子旭
出處:http://bjlhx.cnblogs.com