28
本文基于 Ant Design Pro 1.1.0 版本,参考前请注意版本信息。

Ant Design Pro 是蚂蚁金服团队在 Ant Design 的设计规范与组件库基础上推出的一套 React 实现的企业级中后台前端/设计解决方案。

上手

使用方法是直接 clone 其 GitHub 仓库然后执行 npm install,或是安装官方提供的 cli 工具创建项目(但在这过程中也会涉及到 clone 其 GitHub 仓库)。新项目创建后,自带模板页面和工具链,可以快速更改。

git clone --depth=1 https://github.com/ant-design/ant-design-pro.git my-project
cd my-project
npm install

对于开发者而言,要做的当然是将项目快速适配自己的需求。官方提供了中文文档,但其中内容组织较为零碎。在这里和大家简单地以示例页面中的标准列表为例子,做一个整理,希望能帮助到大家快速上手这个框架。

官方示例中的code标准列表/code

安装完成后,我们运行 npm run start 来启动本地开发服务器,稍等片刻脚本就会自动完成打包。Ant Design Pro 默认通过只需浏览器单方面就可处理的 HashHistory 来完成路由。如果要切换为 BrowserHistory,那在 src/index.js 中也有对应的内容可以直接修改,但需要在后端服务器进行相应路由配置。

从路由到组件

我们在左侧的导航栏点击 列表页 > 标准列表 后,可以进入到上面截图所示的页面。导航栏的内容在 src/common/menu.js 中,

/* 导航栏记录
 * 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.jspath 所指向的路径对应于 src/common/router.js 中的路由记录。

/* 路由记录
 * 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 1 的 Array,component 即为该路由记录对应的实际组件。

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

顺藤摸瓜,我们打开 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: 5,
      },
    });
  }

  render() {
    return (
      <PageHeaderLayout>{/* 具体页面内容 */}</PageHeaderLayout>
    );
  }
}

@connect 装饰器

首先的组件写法中调用了 dva 所封装的 react-redux@connect 装饰器,用来接收绑定的 list 这个 model 对应的 redux store。注意到这里的装饰器实际除了 app.state.list 以外还实际接收 app.state.loading 作为参数,这个 loading 的来源是 src/index.js 中调用的 dva-loading 2 这个插件。

/*
* src/index.js
*/
import createLoading from 'dva-loading';
app.use(createLoading());

它返回的信息包含了 global、model 和 effect 的异步加载完成情况。

{
  "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,
      };
    },
    /* ... */
  },
};

后端模拟数据

通过上面的分析,我们可以看到 list/fetch 会造成带上 payload 的对 src/services/apiqueryFakeList 的一次异步请求。

export async function queryFakeList(params) {
  return request(`/api/fake_list?${stringify(params)}`);
}

走到这一步的时候,后端交互开始产生了。我们退到根目录下的 .roadhogrc.mock.js 这个文件。Ant Design Pro 直接沿用了 roadhog 中自带的 mock 功能,在这里我们简单搜索一下就能看到具体的 mock 转发配置。

import { getActivities, getNotice, getFakeList } from './mock/api';

const proxy = {
  // ...,
  'GET /api/fake_list': getFakeList,
};

那我们转进 mock/api.js 就可以看到 JSON 内容的生成了。

在开发环境中,前后端开发服务器常常部署在 localhost 的不同端口,这个问题常常困扰前后端分离范式的开发者。但有了 roadhog 之后,对上述的 .roadhogrc.mock.js 稍做修改就可以在前端的开发服务器上“构建”一个本地反代,轻松避免这个问题。

本地开发中的跨域问题

大多数浏览器要求 fetch 通过 HTTPS 进行,但对 localhost 有本地赦免,HTTP 下的 fetch 请求并不会遇到问题。(但是如果你给 localhost 做了 hosts 规则那本地开发赦免就不适用了。)

另外,对于本地,浏览器依旧强制执行 CORS 跨域检查,后端端口如果不设置 Access-Control-Allow-Origin 响应头依旧会遇到跨域安全问题。roadhog 提供的这个功能就良好解决了本地开发调试的跨域问题。

// FROM https://github.com/sorrycc/roadhog#proxy
"proxy": {
  "/api": {
    "target": "http://localhost:8080",
    "changeOrigin": true,
    "pathRewrite": { "^/api" : "" }
  }
}

结语

create-react-app 预先配置了基本的工具链,让我们能很快上手纯前端的项目。而 Ant Design Pro 这个脚手架预先配置了更为完整的开发工具链,让我们能快速进行前后端交互的开发。上手的主要难点是理解庞大的工程结构,以及了解更为庞大的依赖链。

作者水平有限,如有纰漏请尽管指出。


  1. 关于 dva 中 Model 的概念,可以参见 Andt Design 项目实践 — 定义 Model,以及 关于dva实际应用的一些经验以及疑惑
  2. 关于 dva-loading,可见 dva-loading 实践用法

sjhstone
124 声望17 粉丝

且潜且跃 跻身来潮 少说多做 势在人为