
三、定义组件构建页面
备注:这里的代码说明均在react相关模块安装好的情况下,安装过程见我的博文《react.js入门必须知道的那些事》.
效果图:

组件拆分思路:
我当时觉得组件拆分得细一点好,所以我把input、button分别做成了一个组件:
var React=require("react"); var MyInput=React.createClass({ render:function(){return (<div className="form-group"><label htmlFor={this.props.labelId} className="col-sm-2 control-label{this.props.labelTip</label><div className="col-sm-10"> <input name={this.props.name} type={this.props.type} onChange={this.props.onChange} className="form-control" id={this.props.labelId} placeholder={this.props.placeholder}/></div></div> ); }}); module.exports=MyInput;var React=require("react"); var Button=React.createClass({ render:function(){return (<button type={this.props.type} className="loginButton">{this.props.ButtonTip}</button>);}})module.exports=Button;由于input有很多都是需要指定的,这种情况下,如果像我这样定义需要传太多参数,而且其实登陆的input大多都是固定且没必要复用的,所以这样其实不大好。这里的input直接写比较好。render:function(){return (<form className="form-horizontal" id="form" ref="dragBox" onSubmit={this.submitHandler} onMouseMove={this.move} onMouseUp={this.endDrag}><DragArea callbackParent={this.onChildChanged} /><div id="form-wrap"><MyInput name="username" labelId={"userId"} labelTip={"用户名"} type={"text"} placeholder={"请输入用户名"} value={this.state.username} onChange={this.handleChange}/><MyInput name="password" labelId={"pw"} labelTip={"密码"} type={"password"} placeholder={"请输入密码"} value={this.state.password} onChange={this.handleChange}/><div className="form-group"><div className="col-sm-offset-2 col-sm-10"><div className="checkbox"><label><input name="checked" type="checkbox" checked={this.state.checked} onChange={this.handleChange} /> 记住我</label></div></div></div> <MyButton type={"submit"} ButtonTip={"登陆"}/></div></form>);备注:因为demo中需要获取真实的dom节点,所以定义了ref。onChildChanged:function(newState){ //因为参数过多,所以把参数放到对象里面,通过对象来传this.setState(newState);},而子组件需要绑定这个函数,如上面的代码:callbackParent={this.onChildChanged}startDrag:function(e){var dragBox=document.getElementById("form");var newState={};var event=e||window.event;event.preventDefault();var computedStyle=document.defaultView.getComputedStyle(dragBox,null);newState.left=computedStyle.left;newState.top=computedStyle.top;newState.currentX=event.clientX;newState.currentY=event.clientY;newState.flag=true;<span style="color: #0000ff;">this.props.callbackParent(newState);</span>} 这样,在子组件中就启动了拖拽开关,并且已经更新了from的相关参数,from的两外两个事件,move和endDrag分别为:move:function(event){var e = event ? event : window.event; //兼容IE的写法if (this.state.flag) {var nowX = e.clientX, nowY = e.clientY;var disX = nowX - this.state.currentX, disY = nowY - this.state.currentY;ReactDOM.findDOMNode(this.refs.dragBox).style.left = parseInt(this.state.left) + disX + "px";ReactDOM.findDOMNode(this.refs.dragBox).style.top = parseInt(this.state.top) + disY + "px";}},endDrag:function(){var computedStyle=document.defaultView.getComputedStyle(ReactDOM.findDOMNode(this.refs.dragBox),null);this.setState({left:computedStyle.left,top:computedStyle.top,flag:false});}至此,拖拽实现!