dva.js是一套数据流的解决方案,其结合了redux的redux-saga异步流的处理方式,dva通过model的概念把一个领域的模型管理起来,包含同步更新 state 的 reducers,处理异步逻辑的 effects,订阅数据源的subscriptions。
1.model的基本配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| export default{ namespace: 'myModel', state: { }, subscriptions: { }, effects: { }, reducers: { } }
|
namespace: model里面全局的命名空间
state: 初始全局状态值
subscriptions: 数据订阅源
effects: 异步数据流处理
reducers: 同步更新state
2.subscriptions数据订阅
subscriptions可以监听从源头获取数据,数据源可以是当前的时间、服务器的 websocket 连接、keyboard 输入、geolocation 变化、history 路由变化等等,这里演示监听浏览器url和键盘数据案例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
2.监听普通url(不带参数) subscriptions: { setup({ dispatch, history }) { return history.listen(({ pathname, query }) => { if(pathname === "/"){ dispatch({type: 'add'}) } } }, }
|
2.reducers同步更新state
这里演示同步更改state数据,和组合state数据(用于下拉加载),假设model初始化了一个state为dateInfo,此时涉及到三种情况:router页面上同步更改state,subscriptions里面更改state和effects里面更改state。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| reducers: { combineData(state, action){ const {payload} = action const {dateInfo} = state if (!payload || !Array.isArray(payload)) return {...state} return { ...state, dateInfo: [...dateInfo, ...payload] } }, change(state, action) { const {payload} = action if (!payload.name) return {...state} return { ...state, [payload.name]: payload.value } }, }
2.subscriptions里面更改state
dispatch({ type: 'change', payload: { name: 'count', value: 0 } })
|
3.effects异步处理数据流
effects用于处理异步数据,采用Generator函数,yield关键字使生成器函数执行暂停,上一个yield执行完毕后在执行下一个yield,假设model初始化了一个state为dateId,此时涉及到三种情况:router页面调用异步处理,subscriptions调用异步处理和effects内部调用。
假设我们导入对应的request请求
1
| import {getUserLists} from '../services/getUserLists'
|
router页面调用和subscriptions调用建立在effects函数之上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
*getUserLists({ payload }, { call, put, select }){ const { dateId } = yield select(state => state.myModel) const data = yield call(getUserLists, 'get', { id: dateId || 0, })
if (!data) return
yield put({type: 'change', payload: {name: 'dataInfo', value: data}}) }
3.subscriptions调用异步处理
dispatch({ type: 'getUserLists', payload: 'params' })
|
使用dva.js小结附加
1.避免数组取值报错,对数据进行判断
1 2 3 4
| Array.isArray(arr) && arr.length && arr.map(x => { })
|
2.JSX语法嵌套
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
render(){ return( <div> <ul> { Array.isArray(arr) && arr.length && arr.map((v, i) => { return (<li key={i} style={{fontSize: '20px', color: `${ v=== '特定值' ? 'red' : 'black' }`}}>值为{v}</li>) }) } </ul> </div> ) }
|
3.使用esLint校验的项目应使用===
,不然会报warnings
4.sass预处理,封装通用的sass
按照750的设计稿标准
1 2 3 4 5 6
| $baseFontSize: 7.5; $basisColor: #FFC107;
@function pxToVw($px) { @return $px / $baseFontSize * 1vw; }
|
5.全局定时器的使用
需要在组件挂载完毕的生命周期函数里面调用定时器,需要在组件将要卸载的生命周期函数清除定时器。