本文是对 Flux、Redux、Vuex、MobX 几种经常使用状态管理模式的总结,偏向于概念层面,不涉及过多代码。javascript
状态管理就是,把组件之间须要共享的状态抽取出来,遵循特定的约定,统一来管理,让状态的变化能够预测。html
组件之间一般会有一些共享的状态,在 Vue 或者 React 中咱们通常会将这部分状态提高至公共父组件的 props
中,由父组件来统一管理共享的状态,状态的改变也是由父组件执行并向下传递。这样会致使两个问题:vue
在应用调试过程当中,可能会有跟踪状态变化过程的需求,方便对某些应用场景的复现和回溯。这时候就须要统一对状态进行管理,并遵循特定的约定去变动状态,从而让状态的变化可预测。java
Store 模式是一种相对简单的状态管理模式,通常有如下约定:vuex
store
里(也能够是全局变量)store
中的 state
用于存储数据,由 store
实例维护store
中的 actions
封装了改变 state
的逻辑流程图以下:redux
若是对 state 的变动均经过 actions,那么实现记录变动、保存快照、历史回滚就会很简单,可是 Store 模式并无对此进行强制约束。promise
Flux 是一种架构思想,相似于 MVC 、MVVM 等。数据结构
Flux 把一个应用分红四部分:架构
Notice:app
type
属性赋值一个大写的字符串,代表是常量,加强可维护性,例如:{
type: 'ADD_USER',
payload: {
name: 'user_name'
}
}
复制代码
state
以及用于触发 state
更新的 dispatch
方法等,整个应用仅有单一的 Store。Store 中提供了几个管理 state
的 API:
store.getState()
:获取当前 statestore.dispatch(action)
:触发 state
改变(惟一途径)store.subscribe(listener)
:设置 state
变化的监听函数(若把视图更新函数做为 listener 传入,则可触发视图自动渲染)action.type
更新 state
并返回 nextState
替换原来的 state
的同步的纯函数(对于相同的参数返回相同的返回结果,不修改参数,不依赖外部变量)。即经过应用状态与 Action 推导出新的 state:(previousState, action) => newState
。Reducer 返回一个新的 state总体流程为:Action Creator => action
=> store.dispatch(action)
=> reducer(state, action)
=> state = nextState
。流程图以下:
Redux 还支持中间件,用于管理异步数据流。
Redux 的 Middleware 是对 store.dispatch()
进行了封装以后的方法,可使 dispatch
传递 action 之外的函数或者 promise;经过 applyMiddleware
方法应用中间件。(middleware 链中的最后一个 middleware 开始 dispatch action 时,这个 action 必须是一个普通对象)
经常使用库:redux-actions, redux-thunk, redux-promise 。
const store = createStore(
reducer,
// 依次执行
applyMiddleware(thunk, promise, logger)
)
复制代码
store.dispatch(action)
),Store 调用 Reducer 计算出新的 state ,若 state 产生变化,则调用监听函数从新渲染 View (store.subscribe(render)
)store.dispatch()
是 View 发出 Action 的惟一途径Vuex 是 Vue 的状态管理模式。
mapState
辅助函数将 state 做为计算属性访问,或者将经过 Store 将 state 注入全局以后使用 this.$store.state
访问store.commit()
调用 Mutationstore.dispatch()
方法触发mapActions
辅助函数将 vue 组件的 methods 映射成 store.dispatch
调用(须要先在根节点注入 store)store.dispatch()
调用 Action ,在 Action 执行完异步操做以后经过 store.commit()
调用 Mutation 更新 State ,经过 vue 的响应式机制进行视图更新MobX 背后的哲学是:
任何源自应用状态的东西都应该自动地得到。
意思就是,当状态改变时,全部应用到状态的地方都会自动更新。
举个栗子:
const obj = observable({
a: 1,
b: 2
})
autoRun(() => {
console.log(obj.a)
})
obj.b = 3 // 什么都没有发生
obj.a = 2 // observe 函数的回调触发了,控制台输出:2
复制代码
参考: