新建项目
create-react-app react20180413
安装路由
npm install react-router-dom -S
跑通路由
删除全部文件后 重新新建index.js
代码如下
import React from 'react';
import ReactDOM from 'react-dom'; import { // HashRouter as Router, //容器 带# BrowserRouter as Router, //容器 推荐用这个 Route //一条路由 } from 'react-router-dom'; function Home () { return <h1>Home</h1> } function User () { return <h1>User</h1> } ReactDOM.render( <Router> <div> <Route path='/user' component={User} /> <Route path='/home' component={Home} /> </div> </Router>,document.querySelector('#root') ); ** 有时候 会报错 A <Router> may have only one child element ** 这个是 说 一个Router 下面只 允许 一个 子组件 所以 <Router> 下面得有一个 <div>包裹起来 可以从外部引入组建 Home User 新建User.js Home.js 例: import React,{Component} from 'react'; export default class Home extends Component{ render(){ return ( <div> Home </div> ) } };
子页面还可以嵌套路由
import React,{Component} from 'react';
import {
Route, //一条路由
Link
} from "react-router-dom";
import UserList from './UserList';
import UserAdd from './UserAdd';
import UserDetail from './UserDetail';
export default class User extends Component{
render(){
return (
<div className="row">
<div className="col-sm-2"> <ul className="nav nav-stacked"> <li><Link to="/user/list">用户列表</Link></li> <li><Link to="/user/add">新增用户</Link></li> </ul> </div> <div className="col-sm-10"> <ul className="nav nav-stacked"> <Route path="/user/list" component={UserList}/> <Route path="/user/add" component={UserAdd}/> <Route path="/user/detail/:id" component={UserDetail}/> </ul> </div> </div> ) } };
路由传递参数 直接在后面追加 /name
<Link key={index} to={"/user/detail/" + user.id}><button className="list-group-item">{user.name}</button></Link>
路由参数获取
在 this.props 是个数组在它里面 有以下参数
history 跳转路径 路径
{
history:action:"PUSH"
block:ƒ block()
createHref:ƒ createHref(location)
go:ƒ go(n)
goBack:ƒ goBack()
goForward:ƒ goForward()
length:50
listen:ƒ listen(listener)
location:{pathname: "/user/detail/1524472305217", search: "", hash: "", state: undefined, key: "xekkjj"} push:ƒ push(path, state) } location 当前路径的信息 { push:ƒ push(path, state) replace:ƒ replace(path, state) __proto__:Object location:hash:"" key:"xekkjj" pathname:"/user/detail/1524472305217" //当前路径 search:"" state:undefined } match 匹配结果 如果 匹配上就是 对象 匹配不上就是 null { isExact:true // 是否是 精确匹配 params:{id: "1524472305217"} //路径参数 path:"/user/detail/:id" url:"/user/detail/1524472305217" } let id = this.props.match.params.id; 这样就可以拿到 列表页面传过来的 参数
另外一种渲染方式 匿名组件声明方式
<Route path="/" render={props => <div>新的渲染方式</div>} /> 相当于 在 class 之外 定义一个变量 let Hello = (props) = > { return <div>组建</div> } <Route path="/" component={Hello} />
精确匹配 -> exact
<Route exact path="/" component={Hello} />
Switch 路由 从上往下匹配 若匹配到一个 下面的就不回去匹配了 更不会去渲染了
import React from "react";
import {
// HashRouter as Router, //容器
BrowserRouter as Router, //容器
Route, //一条路由
Link,
} from "react-router-dom";
import "bootstrap/dist/css/bootstrap.css";
import User from "./User";
import Home from "./Home";
import Profile from "./Profile";
export default (
<Router >
<div>
<nav className="navbar navbar-inverse"> <div className="container-fluid"> <div className="navbar-header"> <div className="navbar-brand"> router </div> </div> <ul className="nav navbar-nav"> <li><Link to="/home">首页</Link></li> <li><Link to="/user">用户管理</Link></li> <li><Link to="/profile">个人设置</Link></li> </ul> </div> </nav> <div className="container"> <div className="row"> <div className="col-sm-12"> <Switch> <Route path="/" render={props => <div>首页</div>}/> <Route path="/:name" render={props => <div>{props.match.params.name}</div>} /> <Route path="/home" component={Home}/> <Route path="/user" component={User}/> <Route path="/profile" component={Profile}/> </Switch> </div> </div> </div> </div> </Router> )
实现 登录 和 退出
- 自己新建一个 组建 去写判断的规则
- 当通过函数来定义组件的时候参数是属性对象
- 当一个组件不需要状态的时候可以用函数来声明
当用户访问个人设置的时候,先判断此用户是否登录.如果已经登录则可以直接显示个人设置页面.如果此用户未登录,那么则跳转到登录页面进行登录,如果登录成功则自动跳转回登录前的页面
- 代码如下
/*
* 结构赋值
* props = {path:"/profile",component:Profile}
* ...rest 其余运算符
* rest = {path:"/profile"}
*/
import React from 'react';
import {Redirect,Route} from 'react-router-dom'; //Redirect 重定向 export default function ({component:Component,...rest}) { // ...rest 展开 return <Route {...rest} render={ (props) => sessionStorage.getItem('login')?<Component />:<Redirect to={{ //跳到哪里 pathname:'/login', // 记录从哪里调过来的,后面取的时候会从这里取 state:{from:props.location.pathname} }} /> } /> }
跳到login页面
import React from 'react';
export default function (props) {
return <div className="jumbotron">
<div className="container">
<h1>Hello!</h1> <p>你还没登录,请登录!</p> <p><button className="btn btn-primary btn-lg" onClick={ () => { sessionStorage.setItem('login','true'); props.history.push(props.location.state.from); }} >登录</button></p> </div> </div> }
- 点击按钮后 跳到 之前重定向前的页面 props.history.push(props.location.state.from);
route -> children 不管当前路径是否匹配的上,都会渲染对应的组件
import React from "react";
import {Route,Link} from "react-router-dom";
export default function ({to,label}) { return ( //不管匹配不匹配都会去return 出东西 <Route path={to} children={({match}) => { console.log(match) //若匹配则 给一个选中的类名 return <li className={match?'active':''}><Link to={to} >{label}</Link></li> }}/> ) }
route -> Prompt 路径跳转的 时候进行的提示
- <Prompt when = {this.state.blockimg} message = { () => { return
你确定要离开本页面
; }} /> - Prompt 有两个参数 第一个 when 什么时候提示 传入bool类型
-
第二个 message 提示什么内容
import React,{Component} from 'react';
import {Prompt} from "react-router-dom";
export default class UserAdd extends Component{ constructor (props) { super(props); this.state = { blockimg : false, //是否组织跳转 默认不阻止 } } //点击提交按钮时 handleSubmit = () =>{ let name = this.name.value; console.log(name); // 从缓存中获取用户列表的字符串 null 字符串 let userStr = localStorage.getItem('users'); let users = userStr?JSON.parse(userStr):[]; //添加字符串对象 users.push({id:Date.now(),name}); //存到缓存 localStorage.setItem('users',JSON.stringify(users)); //把离开本页面的提示关掉 this.setState({ blockimg:false },()=>{ //跳转到用户列表 this.props.history.push('/user/list'); }); } //input 改变的时候 handleChange = (event) => { let value = event.target.value; this.setState({ blockimg:value&&value.length>1?true:false }); } render(){ return ( <div> <Prompt when = {this.state.blockimg} message = { (location) => { return `你确定要离开本页面${location.pathname}`; }} /> <form onSubmit={this.handleSubmit}> <div className="input-group"> <input type="text" className="form-control" placeholder="请输入用户姓名" onChange={this.handleChange} ref={ref=>this.name=ref} /> <span className="input-group-btn"> <button className="btn btn-primary" type="submit">添加</button> </span> </div> </form> </div> ) } };
404 页面
import React from 'react';
export default (props) => {
return <div className="jumbotron">
<div className="container"> <h1>抱歉!</h1> <p>没找到您访问的页面!</p> <p><button className="btn btn-primary btn-lg" onClick={ () => { props.history.push('/'); }} >点击跳回首页</button></p> </div> </div> }
- 在 app页面引用
<Route component={Notfound}/>