行走的dva
一、dva 框架介绍
1、dva 是什么
dva 是阿里前端架构师 sorrycc 带 team 研发的一套轻量级前端框架,其目的是尽量避免前端重复性劳动,简化开发流程。
实际上也确实如此,一个简单的 CRUD 模块只需要1-2个小时即可完成前端作业。
2、dva 脚手架是什么
前面说到 dva 是一个框架,那么 dva 脚手架就是这个框架的具体表现。
我们习惯于称:创建一个 dva 脚手架,实际上就是创建一个项目目录。
3、安装 dva-cli 用于初始化项目:
npm install -g dva-cli
# 或
yarn global add dva-cli
mkdir your-project 创建项目目录
cd your-project 并进入该目录
dva init 初始化项目
4、目录结构
二、项目结构分析
- mock 存放用于 mock 数据的文件;
- public 一般用于存放静态文件,打包时会被直接复制到输出目录(./dist);
- src 文件夹用于存放项目源代码;.editorconfig 编辑器配置文件
- asserts 用于存放静态资源,打包时会经过 webpack 处理;
- components 用于存放 React 组件,一般是该项目公用的无状态组件;
- models 用于存放模型文件
- routes 用于存放需要 connect model 的路由组件;
- services 用于存放服务文件,一般是网络请求等;
- utils 工具类库
- router.js 路由文件
- index.js 项目的入口文件
- index.css 一般是共用的样式
- .eslintrc ESLint配置文件
- .gitignore Git忽略文件
- .roadhogrc.mock.js Mock配置文件
- .webpackrc 自定义的webpack配置文件,JSON格式,如果需要 JS 格式,可修改为 .webpackrc.js
数据的改变发生通常是通过用户交互行为或者浏览器行为(如路由跳转等)触发的,当此类行为会改变数据的时候可以通过 dispatch 发起一个 action,如果是同步行为会直接通过 Reducers 改变 State ,如果是异步行为(副作用)会先触发 Effects 然后流向 Reducers 最终改变 State,所以在 dva 中,数据流向非常清晰简明,并且思路基本跟开源社区保持一致
基础概念
1、Model
Model 是 dva 最重要的部分,可以理解为 redux、react-redux、redux-saga 的封装。
通常项目中一个模块对应一个 model,一个基本的 model 如下:
namespace
是该 model 的命名空间,同时也是全局 state
上的一个属性,只能是字符串,不支持使用 .
创建多层命名空间。
state
是状态的初始值。
reducer
类似于 redux 中的 reducer,它是一个纯函数,用于处理同步操作,是唯一可以修改 state
的地方,由 action
触发,它有 state
和 action
两个参数。
effects
用于处理异步操作,不能直接修改 state
,由 action
触发,也可触发 action
。它只能是 generator
函数,并且有 action
和 effects
两个参数。第二个参数 effects
包含 put
、call
和 select
三个 字 段,put
用于触发 action
,call
用于调用异步处理逻辑,select
用于从 state
中获取数据。
subscriptions
用于订阅某些数据源,并根据情况 dispatch 某些 action,格式为 ({ dispatch, history }, done) => unlistenFunction
。
如上的一个 model,监听路由变化,当进入 /user
页面时,执行 effects
中的 fetch
,以从服务端获取用户列表,然后 fetch
中触发 reducers
中的 save
将从服务端获取到的数据保存到 state
中。
注意,在 model 中触发这个 model 中的 action
时不需要写命名空间,比如在 fetch
中触发 save
时是 { type: 'save' }
。而在组件中触发 action
时就需要带上命名空间了,比如在某个组件中触发 fetch
时应该是 { type: 'user/fetch' }
。
当写完 model 和组件后,需要将 model 和组件连接起来。dva 提供了
connect
方法,其实它就是 react-redux
的 connect
。用法如下:
connect 后的组件除了可以获取到 dispatch
和 state
,还可以获取到 location
和 history
。