antd pro 新增模塊的步驟

index.js是整個項目的入口文件。node

// 1. Initialize
const app = dva({
  history: createHistory(),
});

// 2. Plugins
app.use(createLoading());

// 3. Register global model
app.model(require('./models/global').default);

// 4. Router
app.router(require('./router').default);

// 5. Start
app.start('#root');

export default app._store; // eslint-disable-line

找到/src/common/menu.js中進行菜單配置,

在/src/common/router.js的routerConfig中配置路由,其中第一個參數是一個DvaInstance的實例,是index.js文件中定義的;第二個參數是該頁面對應的model,即數據存儲的地方;第三個參數是一個函數,返回對應的頁面。

'/': {
      component: dynamicWrapper(app, ['user', 'login'], () => import('../layouts/BasicLayout')),
    },

dynamicWrapper:web

// wrapper of dynamic
const dynamicWrapper = (app, models, component) => {
  // register models
  models.forEach(model => {
    if (modelNotExisted(app, model)) {
      // eslint-disable-next-line
      app.model(require(`../models/${model}`).default);
    }
  });

  // () => require('module')
  // transformed by babel-plugin-dynamic-import-node-sync
  if (component.toString().indexOf('.then(') < 0) {
    return props => {
      if (!routerDataCache) {
        routerDataCache = getRouterData(app);
      }
      return createElement(component().default, {
        ...props,
        routerData: routerDataCache,
      });
    };
  }
  // () => import('module')
  return Loadable({
    loader: () => {
      if (!routerDataCache) {
        routerDataCache = getRouterData(app);
      }
      return component().then(raw => {
        const Component = raw.default || raw;
        return props =>
          createElement(Component, {
            ...props,
            routerData: routerDataCache,
          });
      });
    },
    loading: () => {
      return <Spin size="large" className="global-spin" />;
    },
  });
};

數據操做在src/models/文件夾下新建一個js文件(對應routerConfig中的model),做爲這個頁面的model,用來定義該頁面須要用到的數據,以及一些函數。在model中存在 namespace(命名空間,用來區分不一樣的頁面之間的數據),state(該命名空間下的數據),effects(一些異步請求的api方法定義在這裏),reducers(用來修改state的一些函數定義在reducers下)

model相似於mvc結構中控制器的角色,其中主要有五個配置項。api

  • namespace
  • model 的命名空間,同時也是他在全局 state 上的屬性,只能用字符串,不支持經過 . 的方式建立多層命名空間。
  • state
  • state的初始值,優先級低於傳給 dva() 的 opts.initialState。
  • reducers key/value 格式定義 reducer,用於處理同步操做,惟一能夠修改 state 的地方。由 action 觸發
  • effects
  • 以 key/value 格式定義 effect。用於處理異步操做和業務邏輯,不 直接修改 state。由 action 觸發,能夠觸發 action,能夠和服務 器交互,能夠獲取全局 state 的數據等等。
  • subscrip
  • 以 key/value 格式定義 subscription。subscription 是訂 閱,用於訂閱一個數據源,而後根據須要 dispatch 相應的 action。在 app.start() 時被執行,數據源能夠是當前的時間、服 務器的 websocket 鏈接、keyboard 輸入、geolocation 變化、 history 路由變化等等。

在model中不直接書寫發起請求的代碼,而是將請求統一放在 /src/services/下,新建一個js文件,存儲各類請求的函數,將這些函數暴露出去,在model中引用。

總體的一個運行流程以下:

  • 進入頁面,在頁面的componentDidMount鉤子函數中調用model的effect中的方法服務器

  • 該方法調用service文件夾下的統一管理的請求函數babel

  • 獲取到服務器返回值,在model的effect中拿到,而且調用model下的reducerwebsocket

  • 調用model的reducers對請求的數據進行處理,將model的state進行改變,頁面自動進行渲染mvc

相關文章
相關標籤/搜索