大魔导师戴戴戴の博文 转载请保留原文链接!

React 实践

写前面 

自从听闻React出世后那阵子 就学了相关的知识 可是一直没有机会实践过!  都已经过了大半年了 再不操刀 可不行!

下面的demo 可以说canvas 来做比较靠谱  但是!

我就要用dom来实现 咱的目的是来实践React的 !

 

 

我是demo

 

效果图:

我们将界面分解成组件形式

这些组件外面 还有个包裹他们的 MotionSegment组件

代码的基础结构:

初始化

 1 import MotionSegment from './MotionSegment';
 2 
 3 _$(()=>{
 4 
 5     const c = _$.color('rgb',{to_number:1});
 6 
 7     const prop = {
 8         sgm_head : {
 9             radius : 50
10             ,color : c
11         }
12         ,sgm_body : {
13             nums : 23
14             ,width : 5
15             ,height : 1
16             ,color : c
17         }
18         ,cir_enemy :{
19             radius : 80
20             ,nums : 10
21         }
22     };
23 
24     React.render(
25         <MotionSegment {...prop}/>
26         ,_$('#place')[0]
27     );
28 
29 });

传递参数对象给MotionSegment  再渲染到#place元素中

 

MotionSegment 组件

import SegmentControl from './SegmentControl';
import CirEnemyControl from './CirEnemyControl';
import ScoreBoard from './ScoreBoard';

import Ev from './Ev';


const MotionSegment = React.createClass({
    render(){
        //.....

        return (
            <div style={c}>
                <SegmentControl 
                    sgm_head={this.props.sgm_head} sgm_body={this.props.sgm_body} 
                    mouse={this.state.mouse}  
                />
                <CirEnemyControl {...this.props.cir_enemy} t={this.state.t}/>
                <ScoreBoard nums={this.props.cir_enemy.nums}/>
            </div>
            
        )
    }
    
    //...
});

export default MotionSegment;

MotionSegment 含有3个子组件 SegmentControl CirEnemyControl ScoreBoard 

有个Ev 全局对象 这个用来控制组件之间的通信用  组件通信有几种方法 。如 传callback 、context 、还有redux等。。

我选用 订阅/发布模式 做通信 ,对于这个demo足够用!

redux 适合大型的应用 ,其他几种我不喜欢= =

 

SegmentControl组件

import SegmentHead from './SegmentHead';
import SegmentBody from './SegmentBody';

const SegmentControl = React.createClass({

  render(t){
    //...
    return(
      <div>
        <SegmentHead {...this.props.sgm_head} mouse={this.props.mouse}/>
        <SegmentBody {...this.props.sgm_body} mouse={this.props.mouse}/>
      </div>
    )
  }
  
  //...
});
export default SegmentControl;

SegmentHead组件

import Ev from './Ev';

const Ev_Type = {
    'sh/pos' : 'SegmentHead/pos'
};

const SegmentHead = React.createClass({
    render(){
        //...
        return (
            <div style={stys}></div>
        )
    }

    //...
});


export default SegmentHead;

 

SegmentBody组件

import Segment from './Segment';

const SegmentBody = React.createClass({
    render(){
        //...

        return (
            <div>
                {
                    body_data.map((v,i)=>{
                        return <Segment key={i} {...body_data[i]}  height={height}/>
                    })

                }
            </div>
        )
    }
    //...
});


export default SegmentBody;

 

Segment组件

const Segment = React.createClass({
    render(){
        //...
        return(
            <div style={stys}></div>
        )
    }
    //...
});


export default Segment;

CirEnemyControl组件

import Ev from './Ev';
import CirEnemy from './CirEnemy';

const Ev_Type = {
    'sh/pos' : 'SegmentHead/pos'
    ,'ce/pos' : 'CirEnemy/pos'
    ,'cec/addScore' : 'CirEnemyControl/addScore'
    ,'cec/success' : 'CirEnemyControl/success'
} 

const CirEnemyControl = React.createClass({
    render(){
        //....
        //
        return(
            <div>
                {    
                    pos_data.map((data,i)=>{
                        return <CirEnemy key={i} i = {i} t={this.props.t} {...data} />
                    })
                }
            </div>

        )
    }
    //...
});
export default CirEnemyControl;

CirEnemy组件

import Ev from './Ev';

const Ev_Type = {
  'ce/pos' : 'CirEnemy/pos'
  ,'ce/click' : 'CirEnemy/click'
};

const CirEnemy = React.createClass({
  //...
  render(){
    
    return(
      <div  style={stys}></div>
    )
  }
  //...
});

export default CirEnemy;

最后个计分的ScoreBoard

import Ev from './Ev';

const Ev_Type = {
    'cec/addScore' : 'CirEnemyControl/addScore'
    ,'cec/success' : 'CirEnemyControl/success'
}

const ScoreBoard = React.createClass({
  //... render(){
var s = `${this.state.score}/${this.props.nums}`; this.state.complete && (s='都被你吃完啦~'); return( <h1 style={this.props.stys}>{s}</h1> ) }
  //... }); export
default ScoreBoard;

大致结构就上面这样子了~

 

有几个的关键的地方讲讲

1 组件之间如何通信的?

2 渲染何时进行的?

3 那个长的像蛇的是怎么做的? dom都能做?

 

 

1、关于通信 一开始我用的传统callback传递来实现父子和姐妹之间的通信。。后面发现套了2层就挺烦了 之后又试了其余几种 最后决定使用订阅发布

接受消息我统统放到componentDidMount 之中  比如 在记分组件中 具体就在

import Ev from './Ev';

const Ev_Type = {
    'cec/addScore' : 'CirEnemyControl/addScore'
    ,'cec/success' : 'CirEnemyControl/success'
}

//...
const ScoreBoard = React.createClass({
    //...
    ,componentDidMount(){

        Ev.on(Ev_Type['cec/addScore'],this.onAddScore);

        Ev.on(Ev_Type['cec/success'],this.onSuccess);
    }
});

export default ScoreBoard;

 CirEnemyControl如果发布了消息  ScoreBoard就会接受到了

 

2、在根组件MotionSegment  开个主循环 实时的传递鼠标坐标位置和时间戳 渲染工作也就顺便做了。。

,componentDidMount(){

        const T = _$.Timer;
        //...

        T.execute();
        T.loop(t=>{

            this.setState({mouse , t});

        });
        
        //...
    }

 

 

3、这个玩意属于骨骼动画了  推荐用canvas做 这里是用dom实现的 有些多余的计算  主要是处理身体那部分 身体其实就是N个节段拼接起来的 利用上个节段的坐标位置 递归计算 需要点处理技巧。。

我之后专门放到canvas里去讨论 此篇主要是来实践React的 先不说~~~

 

*React实践还很少 不能说写的有多好 但终归完成了

如果 有不对 或不严谨的地方 望指正!

 

 

posted @ 2016-04-22 01:16  戴戴戴x  阅读(438)  评论(0编辑  收藏  举报