001-ant design pro 頁面加載原理及過程,@connect 裝飾器

1、概述

  以列表頁中的標準列表爲主react

  

  Ant Design Pro 默認經過只需瀏覽器單方面就可處理的 HashHistory 來完成路由。若是要切換爲 BrowserHistory,那在 src/index.js 中也有對應的內容能夠直接修改,但須要在後端服務器進行相應路由配置。redux

2、詳述

加載過程圖後端

  

 

2.一、菜單→路由→組件

  在左側的導航欄點擊 列表頁 > 標準列表 後,能夠進入到上面截圖所示的頁面。導航欄的內容在 src/common/menu.js 中【或者服務獲取的地址】api

菜單:

      {
        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 即爲該路由記錄對應的實際組件。 app

const dynamicWrapper = (app, models, component) => {...};

  能夠看到:異步

    一、加載路由的時候,會動態加載當前文件下的model文件,也就是對應文件下的src/models/list.js函數

組件:

  src/routes/List/BasicList.js,具體組件。已省略部分代碼fetch

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: 5,
      },
    });
  }

  render() {
    return (
      <PageHeaderLayout>{/* 頁面內容…… */}</PageHeaderLayout>
    );
  }
}

2.二、@connect 裝飾器

  組件寫法中調用了 dva 所封裝的 react-redux 的 @connect 裝飾器,用來接收綁定的 list 這個 model 對應的 redux store。注意到這裏的裝飾器實際除了 app.state.list 之外還實際接收 app.state.loading 做爲參數,這個 loading 的來源是 src/index.js 中調用的 dva-loading這個插件。

/*
* src/index.js
*/
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中使用

一、connect使用

@connect(({ list, loading }) => ({
  list,//①
  loading: loading.models.list,//②
}))

  說明:

    一、connect 有兩個參數,mapStateToProps以及mapDispatchToProps,一個將狀態綁定到組件的props一個將方法綁定到組件的props

    二、代碼①:將實體list中的state數據綁定到props,注意綁定的是實體list總體,使用時須要list.[state中的具體變量]

    三、代碼②:經過loading將上文「數據map一」中的models的list的key對應的value讀取出來。賦值給loading,以方便使用,如表格是否有加載圖標

      固然代碼②也能夠經過key value編寫:loading.effects["list/fetch"]

二、變量獲取

因,在src/models/list.js

export default {
  namespace: 'list',

  state: {
    list: [],
  },

故在view中使用

  render() {
    const { list: { list }, loading } = this.props;

說明:

  定義使用時:list: { list }  ,含義實體list下的state類型的list變量

相關文章
相關標籤/搜索