Store是一个JavaScript状态管理器,主要特性如下:
- 任意组合多个action,实现业务流程控制
- Model独立,高可复用,通常一个Model只用定义一次,可在整个项目中使用
- 单独的ViewModel,与Model完全隔离
- Collection相关操作
- Validator
Store认为:
- 业务流程是有序或独立的,比如
A->B->C
或A|B|C
,一旦业务确定,不太可能出现C->A->B
这样乱序的触发顺序。 - 在action遵从最小粒度设计原则的情况下,一定会出现一个业务流程需要多个action组合完成。
所以Store可以一次派发多个action,如:
store.dispatch([{type: 'action a'}, {type: 'action b'}])
- 可能需要知道当前派发的action执行结果,根据结果来执行下一步操作。所以为
dispatch
函数增加了callback
参数。
由于MVVM可以极方便的将model映射到view,所以很多项目中并没有model的存在,而是将接口数据转换后直接写入到view model。 但在大一些项目中,model数以百计,接口数以千计,如果还是以接口->view model这样的数据管理方式, 将会造成灾难性的后果,抛开代码量增加、同一逻辑多次实现的问题不谈,如果某一接口或model发生了不兼容更新,对维护而言将会造成灾难性的后果。 所以Store强烈建议将model及相关接口单独抽离,以实现复用与统一维护。
Store使用中间件的设计模式;
使用数组管理所有的中间件,当一个行为发生的,依次通知这些中间件,所有中间件处理完成后,将结果传入subscriber
。
执行到某一个中间件时,Store保证其前面的中间件已经执行完成,此时可以直接使用前面中间件产生的结果。
npm install sugo-store
git clone https://github.com/CoinXu/store.git
npm install
npm run test
假设有这样的业务流程:
- 使用
user_id
查询用户信息 - 使用用户信息中的
group_id
查询用户所属用户组的信息
// typescript
import { Store } from 'sugo-store'
interface User {
id: string
name: string
group_id: string
}
interface Group {
id: string
name: string
}
interface State {
user: User
group: Group
}
const store = new Store<State>()
enum Action = { initialize = 'INITIALIZE' }
// 1. 定义user相关中间件
store.use(function(action, state, next){
const { type, payload } = action
switch (type) {
// 查询用户数据
case Action.initialize:
window
.fetch(`/api/user/${payload}/info`)
.then(user => next({ user }))
break
default:
next()
}
})
// 2. 定义用户组中间件
store.use(function(action, state, next){
const { type, payload } = action
switch (type) {
// 由于中间件是有序执行的,所以此时state.user已经获取到了,可以直接使用
case Action.initialize:
window
.fetch(`/api/group/${state.user.group_id}/info`)
.then(group => next({ group }))
break
default:
next()
}
})
// observer
store.subscribe(state => console.log(state))
// 派发初始化action
store.dispatch({
type: Action.initialize,
payload: 'user_record_id'
}, state => console.log(state.user, state.group))
上面的代码是Store最基本的示例,实际上Store提供了一些基础的中间件来更好的组织代的代码。
比如storeViewModelCreator
,StoreValidatorCreator
等
所有支持es3的环境。包括不限于:
- 浏览器: ie7+
- nodejs: 所有版本
https://coinxu.github.io/store/docs/home.html
- Example
- English Docs
MIT