1.why Dva
dva 是基于现有运用架构 (redux + react-router + redux-saga 等)的一层轻量封装,没有引入任何新概念,悉数代码不到 100 行。dva 完成上只管不建立新语法,而是用依靠库自身的语法,比方 router 的定义照样用 react-router 的 JSX 语法的体式格局(dynamic config 是机能的斟酌层面,之后会支撑)。
他最中心的是供应了 app.model 要领,用于把 reducer, initialState, action, saga 封装到一同
app.model({
namespace: 'products',
state: {//State 示意 Model 的状况数据
list: [],
loading: false,
},
subscriptions: [
function(dispatch) {
dispatch({type: 'products/query'});//触发 action 的函数,action 是转变 State 的唯一门路
},
],
effects: {//Effect 被称为副作用,在我们的运用中,最常见的就是异步操纵
['products/query']: function*() {
yield call(delay(800));
yield put({
type: 'products/query/success',
payload: ['ant-tool', 'roof'],
});
},
},
//在dva中reducers聚合积聚的结果是当前model的state 对象。经由过程actions中传入的值,
//与当前 reducers 中的值举行运算取得新的值(也就是新的 state)
reducers: {
['products/query'](state) {
return { ...state, loading: true, };
},
['products/query/success'](state, { payload }) {
return { ...state, loading: false, list: payload };
},
},
});
2.简单明了的Dva数据流向
数据的转变发作通常是经由过程用户交互行动或许浏览器行动(如路由跳转等)触发的,当此类行动会转变数据的时刻能够经由过程 dispatch 提议一个 action,如果是同步行动会直接经由过程 Reducers 转变 State ,如果是异步行动(副作用)会先触发 Effects 然后流向 Reducers 终究转变 State
3.Dva Router掌握
dva 实例供应了 router 要领来掌握路由,运用的是react-router
const app = dva();
import { Router, Route } from 'dva/router';
app.router(({history}) =>
<Router history={history}>
<Route path="/" component={HomePage} />
</Router>
);
4.dva 运用的最简构造(带 model)
dva 供应多个 effect 函数内部的处置惩罚函数,比较经常使用的是 call 和 put。
call:实行异步函数
put:发出一个 Action,类似于 dispatch
教室实战
// 建立运用
const app = dva();
// 注册 Model
app.model({
namespace: 'count',
state: 0,
reducers: {
add(state) { return state + 1 },
},
effects: {
*addAfter1Second(action, { call, put }) {
yield call(delay, 1000);//异步操纵
yield put({ type: 'add' });//类似于dispatch发action
},
},
});
// 注册视图
app.router(() => <ConnectedApp />);
// 启动运用
app.start('#root');
5.AntDesignPro1.0项目中的Dva
1.index.js
const app = dva({
history: createHistory(),//history能够用来跳转路由内含location属性,这里修正history默许接口,其他接口稳定----初始化
});
// 2. Plugins
app.use(createLoading());//加载插件这里应当加载的是加载动画插件
// 3. Register global model
app.model(require('./models/global').default);//将src/modles内里的东西灌进去,经由过程namespace取
// 4. Router
app.router(require('./router').default);//全局挂载路由信息
// 5. Start
app.start('#root');
export default app._store;
2.router.js
export const getRouterData = app => {
const routerConfig = {
'/': {
component: dynamicWrapper(app, ['user', 'login'], () => import('../layouts/BasicLayout')),
},
'/person/personbasetwo': {//增加途径指向引入的组件,这条数据会被getRoutes函数衬着成真正的<Route>包裹的路由
component: dynamicWrapper(app, ['personbaseTwo'], () => import('../routes/Person/PersonBaseTwo')),
},
'/person/baseInfo/:id': {//dynamicWrapper函数会吧[]内里数据放到app的model属性里,app是dva的实例
component: dynamicWrapper(app, ['personbase'], () => import('../routes/Person/PersonBase/BaseInfo')),
},
·······
3.connect衔接model
/*dva的实例app中应当导入了一切的model,好像是在router中导入的,
这里用解构赋值从model中取值,为组件导入props,loading为dva供应的动画插件*/
@connect(({ personbaseTwo, loading }) => ({
personbaseTwo,
searchLoading: loading.effects['personbaseTwo/getList'],
//loding被这个异步函数影响,异步操纵中就为ture,完毕就为false
loading: loading.effects['personbaseTwo/listpage'],
}))//从model中取数据天生本身想要的对象构造经由过程@润饰器放到下面组件中去
class personbaseTwo extends Component {
constructor(props){
super(props);
this.state = {
}
}
componentWillMount(){//组件将要衬着时拿到默许的一页若干条和当前页这些数据
const { personbaseTwo:{pagination} }= this.props;
const { page,pageSize } = pagination;
this.props.dispatch({//转到namespace为personbaseTwo下面的listpage要领拿到页码为page的数据
type:'personbaseTwo/listpage',//接口依据page只去此页数据
payload:{
page,
pageSize,
},
});
}
·······
4.跳转路由
onOk() {//点击肯定实行的函数
const {id}= record;
than.props.dispatch(routerRedux.push({//用来跳转路由的
pathname: `/person/baseInfoTwo/${id}`,//用这个pathname从新衬着路由页面并传ID
}))
},