Ant Design Pro初探

脚手架下载

软件环境:NodeJS,Git
下载步骤:

1、clone代码。其中ant_design 为文件夹名

$ git clone --depth=1 https://github.com/ant-design/ant-design-pro.git ant_design
$ cd ant_design

2、下载依赖

npm install

PS: 下载依赖时设置国内镜像

npm install -g cnpm --registry=https://registry.npm.taobao.org
npm config set registry https://registry.npm.taobao.org

3、运行

npm start

浏览器输入地址 http://localhost:8000,登登登,首页出来了。

Ant Design Pro 浅析

菜单映射

菜单配置主要在文件【config/route.config.js]】,代码如下:

export default [
  {
    path: '/',
    component: '../layouts/BasicLayout',
    Routes: ['src/pages/Authorized'],
    routes: [
      { path: '/', redirect: '/dashboard/analysis' },
      {
        path: '/dashboard',
        name: 'dashboard',
        icon: 'dashboard',
        hideInMenu: false,
        hideChildrenInMenu: false,
        hideInBreadcrumb: true,
        routes: [
          {
            path: '/dashboard/analysis',
            name: 'analysis',
            component: './Dashboard/Analysis',
          },
          {
            path: '/dashboard/monitor',
            name: 'monitor',
            component: './Dashboard/Monitor',
          },
          {
            path: '/dashboard/workplace',
            name: 'workplace',
            component: './Dashboard/Workplace',
          },
        ],
      }
    ]
    }
];

主要看routes列表的元素,这里采用的是约定式路由(UMI).
其中path就是 页面映射的URL,name 是组件的名字, component 这里的当前目录是 src/pages。

页面渲染

import React, { PureComponent, Fragment } from 'react';
import {
    DatePicker, message, version, Button
} from 'antd';

import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import { formatMessage, FormattedMessage } from 'umi/locale';
import style from './default.less';

class MailConfig extends PureComponent {
    render() {
        return (
            <PageHeaderWrapper
                title={<FormattedMessage id="app.forms.message.email" />}
            >
                <div className="App">
                    <p>Current antd version: {version}</p>
                    <p>Please fork this codesandbox to reproduce your issue.</p>
                    <p>请 fork 这个链接来重现你碰到的问题。</p>
                    <Button type="primary">Hello</Button>
                </div>
            </PageHeaderWrapper>
        );
    }
}

export default MailConfig; 

ant-design:所有的页面都保存为JS再进行渲染。
import : 根据实际需要引入相应的组件。
@/components/PageHeaderWrapper: 显示页面标题内容的组件。
'umi/locale‘: 国际化资源配置,配置文件在 src/locales 目录下。
export default MailConfig: 表示将当前页面嵌套在当前主题模版里。

界面定义数据交互

官方讲解:

  1. UI 组件交互操作;
  2. 调用 model 的 effect;
  3. 调用统一管理的 service 请求函数;
  4. 使用封装的 request.js发送请求;
  5. 获取服务端返回;
  6. 然后调用 reducer 改变 state; 更新 model。

讲人话:
1、每个页面都是通过一个叫做model的文件做数据配置;
2、调用通用的请求行数;
3、使用request.js提交请求;
4、获取响应信息,进行渲染。

show u the code:

以查询表格(TableList.js)为例。

 componentDidMount() {
    const { dispatch } = this.props;
    dispatch({
      type: 'rule/fetch',
    });
  }

componentDidMount: 加载数据函数

再看同级目录下models/rule.js

import { queryRule, removeRule, addRule, updateRule } from '@/services/api';
...
  effects: {
    *fetch({ payload }, { call, put }) {
      const response = yield call(queryRule, payload);
      yield put({
        type: 'save',
        payload: response,
      });
    },

使用了后缀模糊匹配。
yield call(queryRule, payload) :queryRule 表示调用了services/api.js 的queryRule, payload 表示传递的参数。

services/api.js 对应的函数如下:

export async function queryRule(params) {
  console.log("rule");
  return request(`/api/rule?${stringify(params)}`);
}

demo 中的请求都是通过mock来模拟后端的返回数据。这里的请求对应的mock文件是mock/rule.js

import { parse } from 'url';

// mock tableListDataSource
let tableListDataSource = [];
for (let i = 0; i < 46; i += 1) {
  tableListDataSource.push({
    key: i,
    disabled: i % 6 === 0,
    href: 'https://ant.design',
    avatar: [
      'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
      'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
    ][i % 2],
    name: `TradeCode ${i}`,
    title: `一个任务名称 ${i}`,
    owner: '曲丽丽',
    desc: '这是一段描述',
    callNo: Math.floor(Math.random() * 1000),
    status: Math.floor(Math.random() * 10) % 4,
    updatedAt: new Date(`2017-07-${Math.floor(i / 2) + 1}`),
    createdAt: new Date(`2017-07-${Math.floor(i / 2) + 1}`),
    progress: Math.ceil(Math.random() * 100),
  });
}

function getRule(req, res, u) {
  let url = u;
  if (!url || Object.prototype.toString.call(url) !== '[object String]') {
    url = req.url; // eslint-disable-line
  }

  const params = parse(url, true).query;

  let dataSource = tableListDataSource;

  if (params.sorter) {
    const s = params.sorter.split('_');
    dataSource = dataSource.sort((prev, next) => {
      if (s[1] === 'descend') {
        return next[s[0]] - prev[s[0]];
      }
      return prev[s[0]] - next[s[0]];
    });
  }

  if (params.status) {
    const status = params.status.split(',');
    let filterDataSource = [];
    status.forEach(s => {
      filterDataSource = filterDataSource.concat(
        dataSource.filter(data => parseInt(data.status, 10) === parseInt(s[0], 10))
      );
    });
    dataSource = filterDataSource;
  }

  if (params.name) {
    dataSource = dataSource.filter(data => data.name.indexOf(params.name) > -1);
  }

  let pageSize = 10;
  if (params.pageSize) {
    pageSize = params.pageSize * 1;
  }

  const result = {
    list: dataSource,
    pagination: {
      total: dataSource.length,
      pageSize,
      current: parseInt(params.currentPage, 10) || 1,
    },
  };

  return res.json(result);
}

function postRule(req, res, u, b) {
  let url = u;
  if (!url || Object.prototype.toString.call(url) !== '[object String]') {
    url = req.url; // eslint-disable-line
  }

  const body = (b && b.body) || req.body;
  const { method, name, desc, key } = body;

  switch (method) {
    /* eslint no-case-declarations:0 */
    case 'delete':
      tableListDataSource = tableListDataSource.filter(item => key.indexOf(item.key) === -1);
      break;
    case 'post':
      const i = Math.ceil(Math.random() * 10000);
      tableListDataSource.unshift({
        key: i,
        href: 'https://ant.design',
        avatar: [
          'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
          'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
        ][i % 2],
        name: `TradeCode ${i}`,
        title: `一个任务名称 ${i}`,
        owner: '曲丽丽',
        desc,
        callNo: Math.floor(Math.random() * 1000),
        status: Math.floor(Math.random() * 10) % 2,
        updatedAt: new Date(),
        createdAt: new Date(),
        progress: Math.ceil(Math.random() * 100),
      });
      break;
    case 'update':
      tableListDataSource = tableListDataSource.map(item => {
        if (item.key === key) {
          Object.assign(item, { desc, name });
          return item;
        }
        return item;
      });
      break;
    default:
      break;
  }

  return getRule(req, res, u);
}

export default {
  'GET /api/rule': getRule,
  'POST /api/rule': postRule,
};

数据渲染
在页面定义render函数

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

        const { selectedRows, modalVisible, updateModalVisible, stepFormValues } = this.state;
        return (
            <PageHeaderWrapper title="查询表格">
                <Card bordered={false}>
                    <div className={styles.tableList}>
                     
                        <StandardTable
                            selectedRows={selectedRows}
                            loading={loading}
                            data={data}
                            columns={this.columns}
                            onSelectRow={this.handleSelectRows}
                        // onChange={this.handleStandardTableChange}
                        />
                    </div>
                </Card>
             
            </PageHeaderWrapper>
        );

至此,数据获取并渲染完毕。

后台数据交互

不适用mock,使用真实的服务器接口设置如下:
1、在config/config.js 开启proxy

 proxy: {
    '/test': {
      target: 'http://localhost:9001',
      changeOrigin: true,
      pathRewrite: { '^/test': '/config/email' },
    },
  },

代理规则是将含有/test的请求链接中的以/test开头的内容做替换。
如链接为: http://localhost:8000/test/sendMail
经过代理后变成 http://localhost:9001/config/email/sendMail

PS: 转换过程在内部完成,对外还是显示 http://localhost:8000/test/sendMail

2、启动后台项目

3、启动ant-design

npm run start:no-mock

至此,数据加载完成。

顺便补摸鱼的中的坑:
1、返回的JSON串字段名注意别使用前端关键字,测试中用了 data和result 数据均显示不了。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值