Skip to content

九、dva

1.简介

dva首先是一个基于redux和redux-saga的数据流方案,然后为了简化开发体验,dva还额外内置react-routerfetch口,所以也可以理解为一个轻量级的应用框架

2.脚手架

1.安装

bash
cnpm i dva-cli -g
# 或
yarn add global dva-cli

2.验证

dva -v

3.创建项目

bash
dva new <project>

4.启动

yarn start

3.布局

1.路由

jsx
function RouterConfig({ history }) {
  return (
    <Router history={history}>
      <Switch>
        <Route path="/" exact component={IndexPage} />
        <Route path="/login" exact component={LoginPage} />
        <Route path="/carts" exact component={CartsPage} />
      </Switch>
    </Router>
  );
}

2.样式

导入样式文件,支持css和less

类名写法

jsx
<div className={styles.类名}></div>

3.跳转

1.声明式路由导航

jsx
import {Link} from 'dva/router'

//...

<Link to="/login">跳转</Link>

2.编程式路由导航

jsx
<button onClick={()=>{
        this.props.history.push('/')
    }}>跳转</button>

4.路由模式

安装

bash
yarn add history

修改index.js

index.js

js
//...
import {createBrowserHistory as createHistory} from 'history';
const app = dva({
	history: createHistory(),
});

//...

4.仓库

1.定义仓库

models/carts.js

js
export default {
  // 命名空间
  namespace: 'carts',

  // 状态数据
  state: {
      num: 666
  },

  // action更新state
  reducers: {
    setNum(state, action) {
      // 深拷贝
      let _state = JSON.parse(JSON.stringify(state))
      // 更新(默认的值+传递过来的值
      _state.num += action.payload
      // 返回
      return _state
    }
  },
}

2.激活模型

index.js

js
app.model(require('./models/carts').default);

3.获取

使用connect高阶组件

原理:react-redux被dva封装 从这里面导出connect

mapStateToProps里获取仓库的仓库数据会在到组件的props中,获取就用props.键

jsx
import React, { Component } from 'react'
import { connect } from 'dva';   // connect其实就是dva封装了react-redux里面的

class CartsPage extends Component {
    render() {
        return (
            <div>
                <h1>this is Carts</h1>
                <h1>购物车( {this.props.num} )</h1>
            </div>
        ) 
    }
}

const mapStateToProps = state => {
    console.log('在carts组件中打印状态树数据', state)
    return {
        num: state.carts.num
    }
}

// export default CartsPage
export default connect(mapStateToProps)(CartsPage)

4.更新

使用props.dispatch方法触发仓库中的方法

  • type:仓库中的方法名
  • payload:参数
jsx
<button onClick={()=>{
        this.props.dispatch({
            // 命名空间/reducers名字
            type: 'carts/setNum',
            payload: 2
        })
    }}>更新+2</button>

5.effects

effects 异步处理

  • put 用户触发reducers里的函数 (可以简单为咱们vuex中actions触发mutations 目的更新数据
  • call 用于调用异步函数,如请求接口

effects里的函数时generator函数

models/cart.js

定义方法格式

js
*fn({ payload }, { call, put }) {
    yield put({ type: "xxx" });
},

语法

js
import { postMbLoginApi } from "../services/example";
export default {
  namespace: "carts",
  state: {
    num: 667,
  },
  reducers: {
    setNum(state, action) {
      console.log(111);
      let _state = JSON.parse(JSON.stringify(state));
      _state.num++;
      return _state;
    },
  },
    
  effects: {
    *numAdd({ payload }, { call, put }) {
      yield console.log(111);
    },
    *test2Async({ payload }, { call, put }) {
      yield put({ type: "setNum" });
    },
    *test3Async({ payload }, { call, put }) {
      let res=yield call(postMbLoginApi)
      console.log(res)
    },
  },
};

MIT Licensed