美团
1.创建项目
create-react-app 项目名称
npm start
npm i react-router-dom --save 路由插件
2.项目清空工作
src
App.jsx
index.js
3.项目目录
src
assets #静态资源文件
pages #你的代码
utils #工具
store #做状态管理(flux redux)
App.jsx
index.js
4.项目配置
在index.js文件中
// 1.引入重置样式
import './assets/css/reset.css'
// 2.引入rem.js文件
import './assets/js/rem'
5.项目开发
5-1.login.jsx
import React, { Component } from 'react'
import {Link} from 'react-router-dom'
export default class Login extends Component {
render() {
return (
<div>
<h2>欢迎登陆</h2>
<div>
用户名:
<input type="text"/>
</div>
<div>
密码:
<input type="password"/>
</div>
<div>
<button>欢迎登录</button>
</div>
{/* 连接跳转 */}
<Link to="/index">首页</Link>
<Link to="/movie">电影</Link>
<Link to="/food">美食</Link>
</div>
)
}
}
5-2 index.jsx(页面布局)
import React, { Component } from 'react'
import {Link,Switch,Route,Redirect,NavLink} from 'react-router-dom'
import './index.css'
import Home from '../Home/Home'
import Order from '../Order/Order'
import Mime from '../Mime/Mime'
export default class Index extends Component {
render() {
return (
<div>
{/* 做二级路由出口 */}
<Switch>
<Route path="/index/home" component={Home}></Route>
<Route path="/index/order" component={Order}></Route>
<Route path="/index/mime" component={Mime}></Route>
<Redirect to="/index/home"></Redirect>
</Switch>
{/* 底部导航 */}
{/* 方式二 */}
<footer>
<NavLink to="/index/home" activeClassName="select">首页</NavLink>
<NavLink to="/index/order" activeClassName="select">订单</NavLink>
<NavLink to="/index/mime" activeClassName="select">我的</NavLink>
</footer>
{/* 方式一 */}
{/* <footer>
<Link to="/index/home">首页</Link>
<Link to="/index/order">订单</Link>
<Link to="/index/mime">我的</Link>
</footer> */}
</div>
)
}
}
5-3.home.jsx(4种连接跳转方式)
import React, { Component } from 'react'
import {Link,NavLink} from 'react-router-dom'
export default class Home extends Component {
toMovie(){
// console.log(this.props);
this.props.history.push('/movie')
}
toFood(){
this.props.history.push('/food')
}
toReplace(url){
this.props.history.replace(url)
}
render() {
return (
<div>
<h3>1.Link</h3>
<Link to="/movie">电影</Link>
<Link to="/food">美食</Link>
<h3>2.NavLink</h3>
<NavLink to="/movie">电影</NavLink>
<NavLink to="/food">美食</NavLink>
<h3>3.push</h3>
<button onClick={()=>this.toMovie()}>电影</button>
<button onClick={()=>this.toFood()}>美食</button>
<h3>4.replace</h3>
<button onClick={()=>this.toReplace('/movie')}>电影</button>
<button onClick={()=>this.toReplace('/food')}>美食</button>
</div>
)
}
}
5-3.movie.jsx(列表展示方式)
import React, { Component } from 'react'
import {Link} from 'react-router-dom'
import Item from './components/Item'
export default class Movie extends Component {
constructor(){
super()
this.state = {
movieList : [
{id:1,name:'你好,李焕英'},
{id:2,name:'哥斯拉'},
{id:3,name:'阿凡达'}
]
}
}
render() {
const {movieList} = this.state
return (
<div>
<h2 style={{textAlign:'center'}}>电影列表</h2>
{/* 方式一:列表展示 li */}
<ul>
{movieList.map(item=>(
<li key={item.id} style={{background:'pink'}}>电影名称为:{item.name}</li>
))}
</ul>
<hr/>
{/* 方式二:列表展示 使用Link */}
{movieList.map(item=>(
<div key={item.id} style={{background:'green'}}>
<Link style={{color:'white'}} to="">电影名称为:{item.name}</Link>
</div>
))}
{/* 方式三: 列表展示 组件 */}
{movieList.map(item=>(
<Item key={item.id} i={item}></Item>
))}
</div>
)
}
}
5-4.movieDetail.jsx(接收传参)
import React, { Component } from 'react'
export default class MovieDetail extends Component {
render() {
console.log(this.props.match.params.id);
return (
<div>
MovieDetail
</div>
)
}
}
5-5.foodDetail.jsx(接收参数)
import React, { Component } from 'react'
import querystring from 'querystring'
export default class FoodDetail extends Component {
render() {
// console.log(this.props);
// 方式一
// let search = this.props.location.search;// ?id=1&name=aaa&age=20
// let sear = search.slice(1);//id=1&name=aa&age=20
// let arr = sear.split('&');//['id=1','name=aa','age=20']
// let result = {};
// arr.forEach(item=>{
// let aa = item.split('=');//[id,1] [name,aa] [age,20]
// result[aa[0]] = aa[1];//result = {id:1}
// })
// 方式二
let result = querystring.parse(this.props.location.search.slice(1))
console.log(result);
return (
<div>
FoodDetail
</div>
)
}
}
5-6.返回(GoBack.jsx)
import React, { Component } from 'react'
import {withRouter} from 'react-router-dom'
class GoBack extends Component {
render() {
return (
<button onClick={()=>this.back()}>返回</button>
)
}
back(){
this.props.history.go(-1);
// this.props.history.goBack();
}
}
export default withRouter(GoBack)
6-7.login.jsx(数据双向绑定及登录存储)
import React, { Component } from 'react'
import {Link} from 'react-router-dom'
export default class Login extends Component {
constructor(){
super()
this.state = {
user:{
username:'admin',
password:'111'
}
}
}
changeUser(e,type){
this.setState({user:{
...this.state.user,
[type]:e.target.value
}})
}
login(){
if(this.state.user.username === 'admin' && this.state.user.password === '111'){
sessionStorage.setItem('user',1);
this.props.history.push('/index');
}else{
return alert('用户名或者密码错误')
}
}
render() {
const {user} = this.state
return (
<div>
<h2>欢迎登陆</h2>
<div>
用户名:
<input type="text" onChange={(e)=>this.changeUser(e,'username')} value={user.username}/>
</div>
<div>
密码:
<input type="password" onChange={(e)=>this.changeUser(e,'password')} value={user.password}/>
</div>
<div>
<button onClick={()=>this.login()}>欢迎登录</button>
</div>
{/* 连接跳转 */}
<Link to="/index">首页</Link>
<Link to="/movie">电影</Link>
<Link to="/food">美食</Link>
</div>
)
}
}
6-8.自己配置路由规则做路由守卫
import React, { Component } from 'react'
import {Route,Redirect} from 'react-router-dom'
export default class MyRoute extends Component {
render() {
// console.log(this.props);
const user = sessionStorage.getItem('user');
return (
<div>
{user ? <Route {...this.props}></Route> : <Redirect to="/login"></Redirect>}
</div>
)
}
}
6-9.路由懒加载
import React, { Component } from 'react'
// 参数fn是一个方法
function asyncComponents(fn){
class ZuJian extends Component {
constructor(){
super()
this.state = {
Obj:''
}
}
componentDidMount(){
// console.log(fn());
fn().then(mode=>{
this.setState({Obj:mode.default})
})
}
render() {
const {Obj} = this.state
return (
<div>
{Obj ? <Obj {...this.props}></Obj> : null}
</div>
)
}
}
return ZuJian
}
export default asyncComponents