dudy-flow v1.3.19
DUDY-FLOW
Javascript状态管理工具
概述
组件的状态往往需要和其他组件共享。 对于较好的设计,这种方式往往是松散耦合的。目前比较好的一种实践是基于消息的,类似Rx.js,redux,vuex都在提供这种松散耦合的功能。
dudy-flow希望在这种松散耦合的基础上,还能提供最好的使用体验。
dudy-flow认为一个组件可以发布话题(Topic),其他组件可以订阅(subscribe)话题。每一个话题背后都有一个存储介质(Store)。我们通过派发消息(dispatch)改变Store,然后所有订阅者都会收到Store改变的消息。
安装 & 初始化
npm install dudy-flow --save
npm install babel-plugin-transform-decorators-legacy --save-dev
## or
cnpm install dudy-flow --save
cnpm install babel-plugin-transform-decorators-legacy --save-dev
dudy-flow需要用到decorator,需要在项目的.babelrc中增加
"plugins": ["transform-decorators-legacy"]
和webpack一起使用
import {init_store} from 'dudy-flow'
init_store()
init_store可以重复调用
全局 StoreManager
DUDY-FLOW会在全局绑定一个变量(store), 它的类型是StoreManager,这个对象帮助用户随时随地地操作。
创建一个话题
DUDY-FLOW认为任何时候都可用最小的代价创建一个话题,就是隐式创建话题。 也就是说,用户无需显示声明一个话题,而是有任何订阅者订阅这个话题、或者任何地方想要操作这个话题,那么这个话题就存在了。
// 这个语句隐含创了一个 'some-topic' 的话题
// 同时也创建了一个名称为 'some-topic' 的 Store
store.get("some-topic")
定义Store的变化
dudy-flow认为下一个状态的定义应该非常简单,只需要这样去定义。
store.get('some-topic').next( (state, action) => {
switch(action.type) {
case "SOME-EVENT" :
return {...}
}
})
DUDY-FLOW认为用户无需关心自己不处理的返回值,如果 DUDY-FLOW发现下一个状态为空,或者数据没有改变,那么DUDY-FLOW不会更新状态。
监听Store的变化
const unsub = store.get("some-topic").subscribe( state => {
// 处理store的变化
})
// 取消监听
unsub()
react集成
dudy-flow提供了一个receive装饰器,用于集成react。
@recive('user')
class SomeComponent extends Component{
render(){
const {isUserLoggedIn} = this.props.user
...
}
}
上述例子中,SomeComponent监听Store(user)的变化,然后进行渲染。
同时receive也隐式创建store,receive的第二个参数还可以定义状态变化的函数。
@recive('toast', (state, action) => {
switch(action.type){
case "TOAST-SHOW" :
return {show : true}
...
}
})
class Toast extends Component{
render(){
const {show} = this.props.toast
...
}
}
上述例子,我们开发了一个Toast组件需要全局状态。如果基于redux我们需要定义reducer/action,并且需要显示注册 reducer。在dudy-flow中,可以把事件/store/状态变化等都在一起声明。
state获取
dudy-flow自动注册了store在global上,获取store的状态可以
store.get('toast').state
Counter 例子
import {init_store, receive} from 'dudy-flow'
init_store()
@receive("counter", (state = {v : 1}, action) => {
switch(action.type) {
case "ADD" :
return {v : state.v + 1}
case "SUB" :
return {v : state.v - 1}
}
return state
})
class App extends Component {
constructor() {
super()
this.state = { store: null }
}
render() {
return (
<div>
{this.props.counter.v}
<button onClick={() => store.dispatch({type : "ADD"})}>+</button>
<button onClick={() => store.dispatch("SUB")}>-</button>
</div>
)
}
}
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago