AntDesignPro

2018-05-11 fishedee 前端

1 概述

Ant Desgin Pro,一个功能非常强大开箱即用的后端管理框架。

主要技术为react+react-router+dva+ant design组件。

2 安装

npm install ant-design-pro-cli -g
mkdir my-project && cd my-project
pro new 
npm install
npm start

这样就能启动了

3 布局

Screen Shot 2018-05-11 at 9.11.45 P

在Pro版本中默认就自带有四个Layout

BasicLayout:基础页面布局,包含了头部导航,侧边栏和通知栏。

Screen Shot 2018-05-11 at 9.12.53 P

PageHeaderLayout:带有标准 PageHeader 的布局

UserLayout:抽离出用于登陆注册页面的通用布局

BlankLayout:空白的布局

4 配置

4.1 路由

Screen Shot 2018-05-11 at 9.32.17 P

在/common/routers文件中,在routerConfig中加入component就可以了,第一个参数固定为app,第二个参数为model的名字,第三个参数为component的名字

4.2 菜单

Screen Shot 2018-05-11 at 9.34.12 P

在/common/menu文件中,在menuData中就能配置好左边侧边栏的菜单名字了

4.3 页面

import React, { PureComponent } from 'react';
import PageHeaderLayout from '../../layouts/PageHeaderLayout';

export default class BasicForms extends PureComponent {
    render() {
    return (
      <PageHeaderLayout
        title="基础表单2"
        content="表单页用于向用户收集或验证信息,基础表单常见于数据项较少的表单场景。"
      ></PageHeaderLayout>
     );
    }
}
Screen Shot 2018-05-11 at 9.37.42 P

在配置好路由和菜单以后,我们就可以添加属于自己的一个新页面了。在routes/Dashborad文件夹中添加Test.js文件,填写入以上内容即可。

4.4 模型

let counter = 0;
function sleep(timeout){
  return new Promise(function(next){
      setTimeout(next,timeout);
  });
}

export async function incCounter(count){
    await sleep(100);
    counter += count;
    return counter;
}

在servics/api文件中,加入incCounter的api设计

import { routerRedux } from 'dva/router';
import { message } from 'antd';
import { incCounter, getCounter } from '../services/api';

export default {
  namespace: 'counter',

  state: 0,

  effects: {
    *inc( {payload} , { call ,put}) {
       let counter = yield call(incCounter,payload);
       yield put({
        type: 'save',
        payload:counter,
      });
      message.success('提交成功');
    },
  },

  reducers: {
    save(state, action) {
      return action.payload;
    },
  },
};

使用dva建立一个简单的model,reducers仅仅作为本地数据变更,effects作为有异步作用的触发器

import React, { PureComponent } from 'react';
import PageHeaderLayout from '../../layouts/PageHeaderLayout';
import { connect } from 'dva';
import {
  Button,
  Form,
  Card,
} from 'antd';

@connect(({ counter, loading }) => ({
  counter,
  loading: loading.models.counter,
}))
@Form.create()
export default class CounterForms extends PureComponent {
    inc = ()=>{
        this.props.dispatch({
            type: 'counter/inc',
            payload: 1,
        });
    }
    dec = ()=>{
        this.props.dispatch({
            type: 'counter/inc',
            payload: -1,
        });
    }
    render() {

    const { counter, loading } = this.props;
    console.log(counter,loading);
    return (
      <PageHeaderLayout
        title="计数器"
        content="计数器测试"
      >
         <Card bordered={false}>
            <div>{counter}</div>
            <Button type="primary" onClick={this.inc}>
               自增
            </Button>
            <Button type="primary" onClick={this.dec}>
               自减
            </Button>
        </Card>
      </PageHeaderLayout>
     );
    }
}

最后使用connect将model的数据与Component串起来了。

Screen Shot 2018-05-11 at 10.23.38 P

就是这么简单

4.5 构建和发布

Screen Shot 2018-05-11 at 10.27.49 P

npm run build 直接生成打包好的html和js文件

5 原理

5.1 路由

功能

  • 登录跳转
  • 主页跳转
  • 嵌套页面
  • 服务器失败页面
  • 无权限页面
  • 找不到页面
  • 动态加载component和model模块
  • 切换页面更换顶端的标题

实现

  • 登录跳转,使用AuthorizedRoute,根据localStorage中的item获取当前的role,然后根据AuthorizedRoute中的authority是否通过,来选择性渲染render,或者redirectPath。更好的办法,应该让登陆态不是从localStorage获取,而是从网络中获取,并且加入一个loading登陆态的状态。
  • 主页跳转,通过加入Redirect路由,from设置为/,to设置为redirect来实现
  • 不同Layout嵌套页面(UserLayout和BasicLayout),通过Switch的顺序来实现,前缀匹配和其他匹配
  • 同一个Layout下的嵌套页面(List页面下不同的tab),提取目前已经匹配的path部分,match.path,然后找出最近可匹配路由来扔进Switch。
  • 服务器失败页面,一般性的错误,使用antd的notification来全局报告失败,对于特定的404,500错误页面,会调用dva的store进行push地址跳转。
  • 无权限页面,BasicLayout中的AuthorizedRoute,它的redirectPath就是403页面。
  • 找不到页面跳转,在Switch的最后一项加入path=/的最终匹配,输出为404的Render。
  • 动态加载component和model模块,使用dva的setDefaultLoadingComponent设置loadingComponent的样式,并且用dynamic生成一个桩组件,它刚开始会呈现loadingComponent的样式,而后加载成功后就会显示本来的组件。
  • 切换顶端的标题,使用react-document-title就可以了。

5.2 表单

这里

注意点:

  • 使用Form.create(),将form以props的方式注入到自定义的组件中
  • 使用Form.Item创建输入组件的标签
  • 使用getFieldDecorator作为输入组件的字段标识和输入校验器
  • 使用Form组件的onSubmit,来作提交前的最后校验
  • 使用Form.create中的onChange回调,可以实时获取数据,并注入计算属性
  • 使用mapPropsToFields可以提前注入Form中的旧数据

5.3 列表

使用Form建立筛选框,使用standardTable展示数据。

Form的筛选框在submit时写入到formValues的state中,当只点击submit时,直接扔掉分页和filter搜索,当改变table来切换时,需要带上分页和filter进行搜索。

另外,传入到standardTable的数据有,column,data(list,pageation),selectedRows

5.4 模态对话框

使用Modal就可以打开一个模态对话框了,visible代表模态对话框是否打开,title代表标题,onOk和onCanel来展示信息。

5.5 请求代理

由于antd启动时是通过8000端口的,但是后端的数据可能来自于mock,也可能来自于其他真实的请求。所以,ant design引入了roadhogrc来做请求代理。

Screen Shot 2018-05-16 at 2.57.12 P

一般情况下,我们只要在.roadhogrc.mock.js中配置好proxy全部走后端服务就可以了。当然,在正式发布时,由npm run build生成静态文件到public目录就可以了。

6 总结

antd在路由处理,model,sercie与layout的联动都是堪称典范的,组件依靠react和设计实现了一个很灵活的用法,基本上满足绝大部分后台系统的需求,这是一个不错的react后台解决方案。唯一的不足就是,修改以后的刷新比较慢,ui反应也不快。

相关文章