九、dva
1.简介
dva首先是一个基于redux和redux-saga的数据流方案,然后为了简化开发体验,dva还额外内置react-router和fetch口,所以也可以理解为一个轻量级的应用框架。
2.脚手架
1.安装
bash
cnpm i dva-cli -g
# 或
yarn add global dva-cli2.验证
dva -v3.创建项目
bash
dva new <project>4.启动
yarn start3.布局
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)
},
},
};