基于种种种种的原因吧,最终决定在项目的web端采用reactjs来做。
##1、React.js
这是大名鼎鼎的脸书出品。一个web前端的js框架。
说起来之前用的是Angular.js,当时对数据双向绑定、页面路由什么的感到十分神奇和惊艳。
这次本来也打算用这个玩,结果发现并不尽如人意,总体来说就是嫌弃麻烦,而且印象中Angular的网络请求对于springMVC的服务端并不是特别兼容。正好大家都说脸书好,就拿来试试。
总体来讲呢,这两个东西都比较适合后端开发人员拿来开发前端。React也是很让人惊艳的框架。实践中感觉React对于界面的掌控力要强过Angular,后者貌似将更多的精力放在了业务逻辑上。
也许就像某些教程上所说的一样,Angular将前端变成了MVC,React则更专注于单纯的V层功能。
总而言之,能自动跟着数据变化改变界面,就满足了我的根本需求。
React的强大之处在于模块化,对于习惯了Class的java程序猿来说简直不要太容易理解。
2、简单入门
既然决定了开工,就上代码吧,第一个要做的东西是一个比赛列表,要根据时间选择器来加载不同日期的比赛。
局部刷新Ajax什么的倒是也能做,不过写界面从来都不是我的强项,还是直接把伟大的UI爸爸写好的html拿过来改一改的好。
界面的实现效果如图所示:

图片来自lol.766.com
首先呢,对于此组件做分析,很容易得出,每一场比赛都可以作为一个单独的组件,于是一个最简单的组件就出来了:
var Match = React.createClass({
render: function () {
var url = "match/";
url+=this.props.matchid;
return (
<li>
<a href={url}>
<div className="march-time">
<p className="day">{this.props.day}</p>
<p className="day-time">{this.props.startTime}</p>
</div>
此处省去一堆没什么卵用的html
</a>
</li>
);
}
});
而组件的调用可以是酱紫的:
<Match day={day} startTime={m.matchdate} matchid={m.id} teamALogo={m.teamA.logo} teamAName={m.teamA.shortname} teamBLogo={m.teamB.logo} teamBName={m.teamB.shortname} result={m.result}/>
通过this.props.xxx就可以拿到在标签中传入的参数了。
在其中需要注意的问题有:
- 要把所有的class都改成className
- 要注意行内的css写作:style={{style:value}}
其实还有很多和标准html不同的地方,毕竟React用的是虚拟DOM,什么时候用到了再说
3、动起来
如果是只能静态展示的页面,其实完全没必要用React来做,接下来才是正事。
我们要点击上面的日期,然后让下面的比赛列表跟着变化。
不管这个应该是怎么说,这些框架对于我来说最大的好处就在于“数据驱动”。只要改数据,页面就会跟着变化。
于是下一步就是分析这个组件有哪些数据。
日期要变,所以上边的日期选择器就是一组数据,为了便于请求,我定义为Date类型。
在数据初始化的方法中如此写道:
getInitialState: function() {
return {
matchlist:[],
centerDay: new Date()
};
},
是哒!没错! 我为了偷懒,只记录了最中间一天(默认今天)的日期,两边的是算出来的~
然后是比赛数据,比赛数据是根据日期通过ajax请求获取的,重点在于更新数据:
componentDidMount: function() {
this.serverRequest = $.get("/match/queryMatchByDate?time="+this.state.centerDay.getTime(),
function (result) {
console.log("已加载比赛数据");
this.setState({matchlist:result});
}.bind(this));
}
这个方法的名字就很明显啊,组件完成加载之后,会调用此方法,我在这里加载初始的数据
在React的组件中,有props和state两个用来存放数据的地方,简单来说,props是从外部传入的,state就是需要变化的数据。
state说到底是一个js对象,使用的时候可以用this.state.prop_name来获取,但是赋值的时候不要这么干!
只有调用this.setState()方法更新的数据,才会驱动页面发生变化。另外此方法的参数不需要传递全部的,哪个改动就传哪个,不会影响到其他的参数。
然后将这些数据分别装进上一步写好的比赛组件中就可以拿去显示了。
React是可以将标签push到数组然后拿去用的哦
下一步是点击事件的工作了。
React的点击事件通过onClick参数进行配置。具体如下:
<a href="#" onClick={this.handleTimeLineClick.bind(this,this.getDateTime(-7))}></a>
handleTimeLinkClick是在此组件中的一个方法。若是不需要传递其余的参数,可以省去后面的.bind,在这里需要传递一个日期,所以用bind,第一个是this,第二个就是要传递的参数。
至此基本的工作就完成了
#4、 输入数据
后面的事情就是我要做一个聊天组件
然后我要拿输入框的数据
然后我就发现需要学习啊。
React中想要获取表单的数据还是挺麻烦的,以一个TextArea来说:
<textarea className="form-control" rows="1" onChange={this.messageHolder} value={this.state.content}></textarea>
重点在于两个:
- 值要用value来指定,而且必须指定为state中的变量。
- 要有onChange方法,否则你会发现此输入框不能输入数据/(ㄒoㄒ)/~~
messageHolder的方法是酱紫的:
messageHolder : function(event){
this.setState({
content:event.target.value
})
},
还记得上面说的么?只有用setState才能改变页面的显示效果!
然后愉快的发送和聊天吧~
send : function(){
if(this.props.ticket==""){
alert("用户尚未登录,请登陆后操作")
}
if(this.state.content=="")
return;
console.log("message content:"+this.state.content);
this.state.socket.emit("sendMessage",{
ticket:this.props.ticket,
message:this.state.content
});
this.setState({
content:""
});
},
有谁看出来怎么做得了吧~那是下一篇的故事了~