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


    本文转自心晴安夏博客:https://www.cnblogs.com/lihuijuan/p/11242976.html

    一、简介

    1、Ant Design Pro

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

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

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

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

     2、umiJS是一个控制路由

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

    二、实践分析

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

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

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

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

    pages触发models中的方法来处理数据,若为异步操作在models中需要调用services中的数据接口方法,在后台未写完时可以通过mock中的模拟数据来调试

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

    数据流向图如下:

    数据的改变发生通常是通过:

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

    当此类行为会改变数据的时候可以通过 dispatch 发起一个 action,如果是同步行为会直接通过 Reducers 改变 State ,如果是异步行为(副作用)会先触发 Effects 然后流向 Reducers 最终改变 State 。

     简单的实例如下:

    1、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;
    复制代码

    2、services/lhj.js文件

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

    3、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;
    复制代码

    4、mock/lhj.js文件

    复制代码
    export default {
        'Get /api/lhj': {
            username: 'lhj',
            age: 24
        },
    }
    复制代码

    三、几个知识点总结:

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

    2、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

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

  • 相关阅读:
    js实现方块弹珠游戏
    学习servlet时出现的一些问题
    简述JAVA类的生命周期
    JAVA高级之路----JAVA多线程
    小计Tomcat的调优思路
    java生成pdf
    git分支在团队中的使用
    程序员修炼内功心法
    学会学习
    如何快速阅读
  • 原文地址:https://www.cnblogs.com/passkey/p/12876069.html
Copyright © 2020-2023  润新知