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。是一個單向的數據流動過程。

相關文章
相關標籤/搜索