React+React-router+webpack重构一个微信小应用(预测宝宝2)(篇幅过长,分2次)

来源:互联网 发布:知无知 谌洪果简历 编辑:程序博客网 时间:2024/04/29 22:58

根据效果图,项目做了以下组件层级:

把页面分成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/";

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/"});

// 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/" />

</Link>

<img className="btn-share" src="img/" />

{this.props.children}

</div>

) }}

完成之后,输入webpack查看打包后的文件,输入命令行webpack -p压缩JS文件。

0 0