根据效果图,项目做了以下组件层级:
把页面分成3个,作为路由切换,app/component中是被三个页面引入的小组件;
上代码详细说明:
1、index.html:
<!DOCTYPE html>
<head>
<metacharset="UTF-8">
<metaname="viewport"content="width=device-width, initial-scale=1.0,
minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<metaname="apple-mobile-web-app-capable"content="yes">
<metaname="apple-mobile-web-app-status-bar-style"content="black">
<metaname="format-detection"content="telephone=no">
<metahttp-equiv="X-UA-Compatible"content="edge">
//css没有在组件内引入,直接页面引入了
<linkrel="stylesheet"type="text/css"href="css/global.css">
<linkrel="stylesheet"type="text/css"href="css/index.css">
<title>预测宝宝</title>
</head>
<body >
<divid="app"></div>
<scriptsrc="bundle.js"charset="utf-8"></script> //这个是webpack打包后输出的JS文件
</body>
</html>
2、主入口文件main.js:
//引入相应的依赖
import React, {PropTypes} from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, hashHistory,IndexRoute,Redirect } from 'react-router';
import FirstPage from './app/FirstPage';
import SecondPage from './app/SecondPage';
import ThirdPage from './app/ThirdPage';
ReactDOM.render((
<Routerhistory={hashHistory}>//使用的是hash,即后面是#
<Routepath="/"> //此处不写会报错
<IndexRoutecomponent={FirstPage}/>//默认加载第一页,以下为3个同级路由,没有嵌套
<Routepath="/FirstPage"component={FirstPage}/>
<Routepath="/SecondPage"component={SecondPage}/>
<Routepath="/ThirdPage"component={ThirdPage}/>
</Route>
</Router>), document.getElementById('app'))
3、FirstPage.js
//引入相应的依赖,特别是路由模块,Link为a标签式跳转,若要验证,不能用Link
import React, {PropTypes} from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, hashHistory,Link,Lifecycle } from 'react-router';
import BigCard from './component/BigCard';
export default class firstPage extends React.Component {
//构造组件初始化状态,url1,url2为子组件BigCard传回的两个URL地址
constructor(props) {
super(props);
this.state={url1: '', url2: '' } }
//路由跳转验证URL是否为空,正确的情况下将URL的数组当成参数传递到下一个路由
handleClick() {
var user={id:[
{url1: this.state.url1},
{url2:this.state.url2}
]};
if(user.id[0].url1&&user.id[1].url2){
hashHistory.push({ pathname: '/SecondPage',query:{bar:user.id[0].url1+","+user.id[1].url2}});
}else{ alert("error"); } }
render() {
return (
<divclassName="m-firstPage">
//一个组件,引用时将相应的参数写入,func为子向父传参数的回调函数,用来获取地址。
<BigCardref="man"
func={(url) =>this.setState({url1:url})}
name="爸爸"sex="man"/>
<BigCardref="woman"
func={(url) =>this.setState({url2:url})}
name="妈妈"sex="woman"/>
<buttonclassName="btn-next"onClick={this.handleClick.bind(this)}>
下一步
</button>
{this.props.children}
</div>
) }}
//此处贴上BigCard的代码:
import React, {PropTypes} from 'react';
import $ from 'jquery';
export default class BigCard extends React.Component{
//男女的状态判断
constructor(props) {
super(props);
let src = this.props.sex == "man"?"img/img_dad@2x.png":"img/img_mom@2x.png";
this.state = {
src: src,
data: null
} }
onChange(){
//接口不对,注释掉了,因此随便上传一张网络图片给父组件 this.props.func("http://pic10.nipic.com/20100927/2457331_105358511000_2.jpg");
let fileObj = this.refs.input.files[0];
let imgage=this.refs.u_image;
this.setState({src: 'http://www.makemebabies.com/img/horizontal-loader.gif'}); imgage.style.height="1.4rem";
imgage.style.top="1.8rem";
//以下为图片上传后的AJAX,以及拿回数据。此处用原生写,只是方便自己其他项目使用的,写法可改。
// var form = new FormData();
// form.append("file", fileObj);
// var xhr = new XMLHttpRequest();
// xhr.open("post", "http://www.baby.com/index/fromdata.php", true);
// xhr.onload = (result) => {
// var datas=eval("("+result.currentTarget.response+")");
// if(datas.status==true){
// this.setState({src: datas.data.face_url});
// this.setState({data: datas.data});
// imgage.style.height="4.16rem";
//imgage.style.top="0.5rem";
////执行子传父的回调函数
// this.props.func(datas.data.face_url);
// }
// else{
// // alert("上传失败 请重新上传图片")
//以下状态
// this.setState({
src: this.props.sex == "man"?"img/img_dad@2x.png":"img/img_mom@2x.png"});
// imgage.style.height="4.16rem";
// imgage.style.top="0.5rem";
// }
// };
// xhr.send(form);
}
render() {
return (
<divclassName="m-card">
<divclassName="cardContent">
<p>选择{this.props.name}照片</p>
<inputref="input"type="file"onChange={this.onChange.bind(this)}/>
<imgsrc="img/camera.png"className="u-camera"alt=""/>
<imgref="u_image"className={this.props.sex}src={this.state.src}/>
</div>
</div>
)
}};
//属性的PropTypes说明,一般最好有这句
BigCard.propTypes = {
sex: React.PropTypes.string.isRequired,
};
4、SecondPage:
import React, {PropTypes} from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, hashHistory,Link,Lifecycle } from 'react-router';
import Button from './component/Button';
import SmallCard from './component/SmallCard';
import ChooseBaby from './component/ChooseBaby';
import Rahmen from './component/Rahmen';
export default class SecondPage extends React.Component{
//路由跳转,此处应该加上与服务器接口的数据传输,没有列出,只是使用网络图片代替全家福图片
handleClick() {
let url="http://www.51ksw.net/uploads/allimg/101205/13552U339-0.jpg";
hashHistory.push({ pathname: '/ThirdPage',query:{bar:url}});
}
render() {
//此方法获取随着第一页路由跳转过来的URL中的参数,","是为了分割字符串然后组成数组。
let user=this.props.location.query.bar;
let urls=user.split(",");
return (
<divclassName="m-choose">
//3个小组件不展示代码,内容类似
<SmallCardurls={urls}/>//把URL地址带入这个子组件并显示在相应位置
<ChooseBaby/> //选择baby类型
<Rahmen/> //相框的数据请求
<buttonclassName="btn-next"onClick={this.handleClick.bind(this)}>
生成全家福
</button>
{this.props.children}
</div> )
}}
5、ThirdPage:
import React, {PropTypes} from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, hashHistory,Link } from 'react-router';
export default class ThirdPage extends React.Component{ render() {
let url=this.props.location.query.bar;
return (
<divclassName="m-showBaby">
<divclassName="showBaby">
<imgsrc={url}alt=""/>
</div>
//普通跳转,因此用Link即可
<Linkto="/FirstPage">
<img className="btn-testAgain" src="img/btn_again@2x.png" />
</Link>
<img className="btn-share" src="img/btn_share@2x.png" />
{this.props.children}
</div>
) }}
完成之后,输入webpack查看打包后的文件,输入命令行webpack -p压缩JS文件。