dva + x


Keywords
dvax
License
ISC
Install
npm install dvax@2.0.9

Documentation

#dvax@1.0.41 更简单的redux

开始使用

安装

> npm install --save dvax

应用入口文件

import dvax from 'dvax'
import App from './App.js'
import { render } from 'react-dom'

render(
	dvax.start(App[,options]), // 传入react应用
	document.getElementById('root')
)

确保运行环境支持Generator、Promise、fetch等API,
以及拓展运算符和Object对象上的assign、keys等方法

或者使用 dvax-starter 脚手架

> npm install -g dvax-starter
> dvax init

Tutorial: 用dvax管理组件数据

引入Model

import { Model } from 'dvax'

定义一个model

const model = {
	namespace: 'app',
	state: { title: 'defaultTitle' } 
}
Model.create(model) // 用Model类的create方法

连接组件

function Example({ title }){
	return <div>{title}</div>
}
Model.connect('app')(Example) // connect中直接写namespace

改变model的状态

change('title',`I'm new title`) // 第一个参数是key,第二个是要更新的valu	

一个完整、独立、可交互、数据驱动的组件

import { Model, connect } from 'dvax'
Model.create({
	namespace: 'app',
	state: { title: 'defaultTitle' }
})
function Example({ title, change }){ // change方法注入,来自connect
	const changeTitle = () => {
		change('title',`I'm new title`) 
	}
	return <div onClick={changeTitle}>{title}</div>
}
Model.connect('app')(Example)

Model类

modelConfig

{
	namespace: 'string', // 唯一必填
	state: 'object', //初始值, 
	effects: { 
		'generator' 
	},
	reducers: { 
		'function'
	}
}

Model.create(modelConfig)

动态创建一个Model

Model.dispatch(action)

同redux的dispatch

Model.change(namespace,key,value)

改变model的state中某一个field/key的值

Model.reduce(namespace,function(state))

替换model的state,
函数的返回值将作为新的state

Model.reduce(namespace,state=>{
	// doSomething with state
    return { ...state }
})

Model.get(namespace)

实时获取state最新的值

Model.get() // 获取所有state
Model.get('namespace') // 获取某个特定的model的state
Model.get().app === Model.get('app') // true

Model.run(namespace,effect)

run方法是运行一个effect,(或者说redux-saga)

Model.run('app',function*({fetch,get,change,reduce}}){
	// get, change, reduce用法见下面的“注入方法”
})

Model.connect(namespace/function)

可以用传统方式传入mapToState函数,也可以写成namespace的格式:

Model.connect('app')(App) // 把App组件连接到'app'model

传入namespace来连接,
被连接的组件会拥有注入方法:reduce、change、run和get,

注入方法和Model上的同名方法的使用方式相似,
他们的区别是:注入方法省略了第一个参数(namespace)

function App({ change, reduce, run }){
	const onClick = () => change('key','value')
	// 或者
	// const onClick = () => Model.change('app','key','value')
	return <div onClick={onClick}>abc</div>
}

Effects

在effects中使用fetch

配置fetch

import dvax from 'dvax'
import Fetch from 'dvax/fetch'
const fetch = Fetch({ // 配置一个fetch实例
	baseUrl: 'http://1.1.1.1:8008',
	headers: { ... },
	bodyTransform(body){ 
		return body
	} 
})
dvax.start(App,{ effects: { fetch } }) // 初始化dvax,并向saga的参数中注入fetch

在model中,

// 定义
{
	namespace:'example',
	effects:{
		*fetchData(params,{ fetch, call, dispatch }){
			const res = yield call(fetch,'data')
			yield dispatch({ type:'someAction', res })
		}
	}
}
// 使用
Model.dispatch({ type:'fetchDate' })

onStart

如果在dvax.start之前,
dispatch effects向远端拿数据会失败,因为fetch还未注入, 可以把dispatch的语句放在onStart中

import dvax,{ Model } from 'dvax'
dvax.onStart(function(){
	// 在配置注入之后,可以正常的dispatch effects
	Model.dispatch({ type: 'fetchData' })
})

全局提示:Toast

import toast from 'dvax/toast'
toast('上传成功',2000,'good')
toast('上传失败',2000,'bad')

淡入淡出动画:fade

import Fade from 'dvax/fade'

<Fade 
	duration={seconds} 
	show={boolean} 
	style={{display:'inline-block'}} 
	className="yourClassName"
	marginTop={"5px"} // 动画出现时离自然文档流位置的距离
>
    <div>abc</div>
</Fade>

Keyboard

import Keyboard from 'dvax/keyboard'

const k = new Keyboard(document.body)
k.keybind(({keyMap,meta,ctrl},catcher)=>{
    catcher(keyMap['n'],{meta,ctrl},e=>create())
    catcher(keyMap['s'],{meta},e=>save())
    catcher(keyMap['backSpace'],{meta,ctrl},e=>del())
})

单元测试工具:test

test( 'title', t=>{
	t('subTitle', ()=>{
		return 'boolean'
	})
})

example:

import test from 'dvax/text'
import xss from 'dvax/xss'
test('Xss', (t) => {
    const string = 'test<a>testatesta'
    t('translated string',()=>{
        return xss.escape(string) === 'test&lt;a&gt;testatesta' 
    })
})