Ant Design Pro 脚手架+umiJS 实践总结

1、简介

一、Ant Design Pro

Ant Design Pro是一款搭建中后台管理控制台的脚手架 ,基于React,dva.js,Ant Designjavascript

(1)其中dva主要是控制数据流向,是纯粹的数据流,用做状态管理html

使用React技术栈管理大型复杂的应用每每要使用Redux来管理应用的状态,然而随着深度使用,Redux也暴露出了一些问题。dva 是一种改良Redux的架构方案,是基于现有应用架构 (redux + react-router + redux-saga 等)的一层轻量封装,简化了redux和redux-saga使用上的诸多繁琐操做。java

(2)ant design是一个基于react打造的一个服务于企业级产品的UI框架。react

 二、umiJS是一个控制路由

以路由为基础,用来控制路由redux

2、实践分析

一、使用Ant Design pro脚手架官网来搭建项目,根据官网教程比较容易,api

根据官网可知,使用ant design pro生成的项目目录为:浏览器

其中最重要的四个文件夹,services、models、mock、pages服务器

  • sevices:数据接口
  • models:数据处理
  • mock:模拟数据
  • pages:页面

pages触发models中的方法来处理数据,若为异步操做在models中须要调用services中的数据接口方法,在后台未写完时能够经过mock中的模拟数据来调试antd

具体来讲,也便是使用dva时,数据流向或者说触发流程为:在pages中的jsx文件中经过dispatch触发models中的js文件中的effects或者reducers中的方法,其中effects中的方法是异步操做,经过yield call(调用接口函数方法名)调用从services中js文件引入的定义好的调用接口方法,而后经过yield put({type: 'reduceres中的方法'});来触发 reducers中的方法来修改state。react-router

数据流向图以下:

数据的改变发生一般是经过:

  • 用户交互行为(用户点击按钮等)
  • 浏览器行为(如路由跳转等)触发的

当此类行为会改变数据的时候能够经过 dispatch 发起一个 action,若是是同步行为会直接经过 Reducers 改变 State ,若是是异步行为(反作用)会先触发 Effects 而后流向 Reducers 最终改变 State 。

 简单的实例以下:

一、welcome.jsx文件

import React from 'react';
import { Form, Input, Button, InputNumber } from 'antd';
import { connect } from 'dva';

//将form注入到props中 @Form.create() //将models中的状态state绑定到props中,解构出myInfo,以myInfo命名绑定到props上 @connect(({lhj:{myInfo}})=>({ //箭头函数返回一个对象,必须在对象外面加上一个括号  myInfo }))

class Welcome extends React.Component{
  handleSubmit = e=>{
 const { form, dispatch } = this.props;
    e.preventDefault();
    //校验输入域的值
    form.validateFields((err,values) =>{
      if(!err){
        console.log(values);
        //验证成功 传入对象{type: 'lhj/check',payload: {...values,}},调用lhj中的check函数,
 dispatch({ type: 'lhj/check', payload: { ...values, } });
      }
    })
    //console.log('submit',form.getFieldValue('username'));
  }
  handleReset = ()=>{
    this.props.form.resetFields();
  }
  render(){
    const { getFieldDecorator } = this.props.form;
      return (
          <div>
              <Form onSubmit={this.handleSubmit} layout="inline">
                <Form.Item label="姓名">
                  {getFieldDecorator('username', {
                    rules: [{required: true, message: 'please input your username'}]
                  })(<Input placeholder="username"/>)}
                </Form.Item>
                <Form.Item label="年龄">
                  {getFieldDecorator('age',{
                    rules: [
                      // {type: 'number', message: 'this must be a number'},
                      {required: true, message: 'please input your age'}
                    ]
                  })(<InputNumber placeholder="age"/>)}
                </Form.Item>
                <Form.Item>
                  <Button type="primary" htmlType="submit">查询</Button>
                </Form.Item>
                <Form.Item>
                  <Button onClick={this.handleReset}>取消</Button>
                </Form.Item>
              </Form>
           {this.props.myInfo.username}-{this.props.myInfo.age}
          </div>

      );
  }
}

export default Welcome;

二、services/lhj.js文件

import request from '@/utils/request';
export async function lhjCheck(params){
    console.log(params,'services')
    return request('/api/lhj', { params });
}

三、models/lhj文件

import {lhjCheck} from '@/services/lhj';
const lhjModel = {
    namespace: 'lhj',
    state: {
        myInfo: {
            username: '',
            age: 0,
        }
    },
    effects: {
        *check({ payload },{ call, put }){
           // console.log(payload,'lhj/check');
            const res = yield call(lhjCheck, payload);
           // console.log(res,'res');//res为从mock中返回的虚拟数据
 yield put({ type: 'checkInfo', payload: { myInfo: res }, })

        },
    },
    reducers: {
        checkInfo(state, { payload }){ console.log(state,payload,'checkInfo'); return { ...state, ...payload,//同名的会覆盖掉  } },
        saveInfo(state){
            return {
                
            }
        },
    }
}

export default lhjModel;

四、mock/lhj.js文件

export default {
    'Get /api/lhj': {
        username: 'lhj',
        age: 24
    },
}

3、几个知识点总结:

一、connect的做用是将组件和models结合在一块儿。将models中的state绑定到组件的props中。并提供一些额外的功能,譬如dispatch。经过connect来绑定model state。意味着Component里能够拿到Model中定义的数据,Model中也能接收到Component里dispatch的action。实现了Model和Component的链接。注意@connect必须放在export default class前面

二、dispatch 函数,经过 type 属性指定对应的 actions 类型,而这个类型名在 reducers(effects)会一一对应,从而知道该去调用哪个 reducers(effects),除了 type 之外,其它对象中的参数随意定义,均可以在对应的 reducers(effects)中获取,从而实现消息传递,将最新的数据传递过去更新 model 的数据(state)

当在组件里发起action时,直接dispatch就好了(

dispatch({ type: `monthCard/query`, payload: {}//须要传递的数据 })

),dva会帮你自动调用effects/reducers。当发起同步action时,type写成'(namespace)/(reducer)'dva就帮你调用对应名字的reducer直接更新state,当发起异步action,type就写成'(namespace)/(effect)',dva就帮你调用对应名字的effect,而后经过yield put调用reducer来实现异步更新state

三、项目的开发流程通常是从设计model state开始进行抽象数据,完成component后,将组件和model创建关联,经过dispatch一个action,在reducer中更新数据完成数据同步处理;当须要从服务器获取数据时,经过Effects数据异步处理,而后调用Reducer更新全局state。是一个单向的数据流动过程。

相关文章
相关标签/搜索