与儿子一起学围棋,上网上找,发现好用的记谱本软件特别少,打算自己做一个。不知能不能克服惰性,完成这个目标。
千里之行,始于足下,今天完成了基础工作:棋盘、棋子组件,并完成了交替落子功能。是React基本功能的很好示范,代码贴一下。下一步就是多组件的状态管理、共享了。
这里刚开始使用的是全局变量来管理状态,后来发现这是一个不太对路的方法,后来改用了全局的一个状态管理类来统一管理状态、处理状态变化、订阅监听、激活事件,后面的文章会介绍。
[b]一、组件go.js[/b]
想出了一个简单的、避免反复修改DOM的办法,将所有棋子组件在初始化都生成,通过状态控制其是否显示、响应点击事件。
var React = require('react');
var ReactDOM = require('react-dom');
require('../../../css/go.css');
//全局变量
window.gGoConfig = new GoConfig();
class GoConfig{
constructor(){
this.index=0;
this.black=true;
}
inc(){
this.index++;
this.black=!this.black;
console.log(this);
}
}
//围棋桌面
class GoDesk extends React.Component {
constructor(props) {
super(props);
this.state = {
refresh: false
};
}
render() {
var self = this;
this.state.refresh=false;
var pieces = [];
for (var i=0; i<19*19; i++){
pieces.push(
<GoPiece color={i % 2==0 ? 'white':'black'} id={'go'+(i+1)} key={'go'+(i+1)}/>
);
}
return <div className="go-desk">
<div className="go-opr">
<GoBtn title="黑走"/>
<GoBtn title="白走"/>
<GoBtn title="黑子"/>
<GoBtn title="白子"/>
</div>
<div className="go-board">
{pieces}
</div>
</div>;
}
}
//可以控制单个按钮的状态
class GoBtn extends React.Component{
constructor(props){
super(props);
this.state={
active:false,
}
this.clickHandle=this.clickHandle.bind(this);
}
clickHandle(event){
this.setState({active:!this.state.active});
console.log(this.state);
}
//<img src=img/{this.state.png} />
render(){
var className = "btn btn-default btn-sm";
if(this.state.active==true)className = className+" active";
return <button className={className} onClick={this.clickHandle}>{this.props.title}</button>;
}
}
//使用bootstap的按钮组,可以不用控制按钮的状态,较为方便,还没有完全走通
class GoBtns extends React.Component{
constructor(props){
super(props);
this.state={};
this.clickHandle=this.clickHandle.bind(this);
}
clickHandle(idx){
this.setState({index:idx});
}
render(){
return <div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary active"><input type="checkbox" autocomplete="off" checked />黑走(pre-checked)</label>
<label class="btn btn-primary"><input type="checkbox" autocomplete="off" />白走</label>
<label class="btn btn-primary"><input type="checkbox" autocomplete="off" />黑子</label>
<label class="btn btn-primary"><input type="checkbox" autocomplete="off" />白子</label>
</div>;
}
}
//棋子
class GoPiece extends React.Component{
constructor(props){
super(props);
this.state={
showNum:false,
num:0,
color:props.color,//or w
current:false,
visibility:'hidden',
}
//设置this,很重要
this.handleClick=this.handleClick.bind(this);
}
handleClick(event){
this.setState({
visibility:this.state.visibility=='hidden'?'visible':'hidden',
color:window.gGoConfig.black==true?'black':'white',
});
//console.log('click, visibility='+this.state.visibility);
window.gGoConfig.inc();
}
render(){
var className="go-piece go-piece-"+this.state.color;
if (this.state.visibility=='hidden') className = className+" go-piece-hidden";
//console.log(className);
return <div className={className} id={this.props.id} onClick={this.handleClick}>
<span style={{visibility:this.state.visibility}}>{this.state.num=window.gGoConfig.index}</span>
</div>;// style={{visibility:this.state.visibility}}
}
}
ReactDOM.render(
<GoDesk />,
document.getElementById('go-container')
);
[b]二、样式文件go.css[/b]
.go-desk{
background-image:url(../img/go/bk.png);
width:100%;
height:100%;
padding:20px;
}
.go-opr{
height:30px;
text-align:center;
margin-bottom:10px;
}
.go-board{
width:800px;
height:800px;
margin:0 auto;
background-image:url(../img/go/board.png);
background-repeat:no-repeat;
padding:20px;
}
.go-piece{
width:40px;
height:40px;
float:left;
background-image:url(../img/go/piece.png);
text-align:center;
line-height:40px;
vertical-align:middle;
font-size:20px;
}
.go-piece span{
}
.go-piece-white{
background-position:-40px 0;
color:black;
}
.go-piece-black{
background-position:0 0;
color:white;
}
.go-piece-hidden{
background-image:none;
}
[b]三、效果[/b]
[align=center]
[img]http://dl2.iteye.com/upload/attachment/0121/7222/f547fb9c-7b4b-33bb-8dde-fb1aad90df2b.png[/img]
[/align]
[b]四、全部代码[/b]
全部代码下载,请看系列文章第一部分,或点击:http://dl.iteye.com/topics/download/536961c7-38a6-38af-b034-c48034f2aa91