新建项目

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>
)

实现 登录 和 退出

  1. 自己新建一个 组建 去写判断的规则
  2. 当通过函数来定义组件的时候参数是属性对象
  3. 当一个组件不需要状态的时候可以用函数来声明
当用户访问个人设置的时候,先判断此用户是否登录.如果已经登录则可以直接显示个人设置页面.如果此用户未登录,那么则跳转到登录页面进行登录,如果登录成功则自动跳转回登录前的页面
  • 代码如下
/* 
 * 结构赋值
 * 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}/>
posted on 2018-05-03 10:24  xzqyun  阅读(272)  评论(0编辑  收藏  举报