Dva.js
Amos Xu
Front End Engineer|前端开发什么是Dva.js?
- 一个处理数据流程的框架。
- 基于redux以及redux-saga
- 额外配置react-router以及fetch
- https://dvajs.com/
快速开始
$ npm install dva-cli -g$ dva -v$ dva new "project name" // 新建dva项目$ cd "project name"$ npm start //启动后可访问8000端口项目入口&创建dva()实例
scr/index.js中会创建dva()实例
import dva from 'dva';import './index.css';
// 1. Initializeconst app = dva();
// 2. Plugins// app.use({});
// 3. Model// app.model(require('./models/example').default);app.model(require('./models/users').default)
// 4. Routerapp.router(require('./router').default);
// 5. Startapp.start('#root');
每一步的概念都在注释中非常简洁明了,最后会被挂载到index.html下id为root的元素上
export interface DvaInstance { /** * Register an object of hooks on the application. * * @param hooks */ use: (hooks: Hooks) => void,
/** * Register a model. * * @param model */ model: (model: Model) => void,
/** * Unregister a model. * * @param namespace */ unmodel: (namespace: string) => void,
/** * Config router. Takes a function with arguments { history, dispatch }, * and expects router config. It use the same api as react-router, * return jsx elements or JavaScript Object for dynamic routing. * * @param router */ router: (router: Router) => void,
/** * Start the application. Selector is optional. If no selector * arguments, it will return a function that return JSX elements. * * @param selector */ start: (selector?: HTMLElement | string) => any,}
export default function dva(opts?: DvaOption): DvaInstance;以上为暴露出的dva实例的定义
核心概念 Model
对于dva.js 而言其核心就是让model模型成为一个可以包含同步state的reducers,异步请求逻辑的effects以及数据的订阅subscriptions.
export interface Model { // 这是源码中对于Model的接口定义(Typescript) namespace: string, state?: any, reducers?: ReducersMapObject | ReducersMapObjectWithEnhancer, effects?: EffectsMapObject, subscriptions?: SubscriptionsMapObject,}由以上源码可知对于模型model而言,其对应的namespace是必不可缺的,而对于state,reducers等来说是可以选择性定义。
export default {
namespace: 'example',
state: {},
subscriptions: { setup({ dispatch, history }) { // eslint-disable-line }, },
effects: { *fetch({ payload }, { call, put }) { // eslint-disable-line yield put({ type: 'save' }); }, },
reducers: { save(state, action) { return { ...state, ...action.payload }; }, },
};
example-model
其中
state为状态(数据)
reducers是同步处理的任务,如删除等
effects为异步操作,其语法来自Generator,可进行异步网络请求。
subscriptions 是一种订阅操作,可以订阅如路由跳转操作。作用类似于拦截器。如下代码就是当路由跳转到/users的时候dispatch一个effects里的fetch异步操作用来加载进入当前路由页面时候的数据。
subscriptions: { setup({ dispatch, history }) { return history.listen(({ pathname, query }) => { if (pathname === '/users') { dispatch({ type: 'fetch', payload: query }); } }); }, },模型model需要在src/index.js中去进行注册
app.model(require('./models/example').default);// 至于后面为什么要.default 可以在代码中直接console.log出require('./models/example') 查看打印出的对象,其中会看到一个defaultconnect 链接
在完成了model的定义之后,在页面中,需要使用connect方法链接model和component
// export default;export default connect(({ xxx }) => ({ xxx,}))(Xxx);此时 在创建组件函数的时候接收即可完成数据的传入