React-router(3)


2019-6-5 React React-router

React 路由

1、react 中的路由

react 使用 react-router

react-router 分为

react-router 核心包全都可以使用

react-router-dom DOM 绑定的包

react-router-native react-native 使用的

react-router-config 做静态路由的

1.1 路由的基本使用

import React from 'react'
import {
  //hashRouter  通过路径里的hash里面实现的 开发用这个 browerRouter 通过H5 的hestory 实现的 上线用这个
  HashRouter, //表示一个路由的跟容器,将来所有和路由相关的东西都需要包裹在这个里面 ,一个网站只需要一个hashrouter 就可以了
  Route, //规则 在route上有两个比较重要的属性 path component
  Link //表示一个路由的连接  还有vue 里面 router-link
} from 'react-router-dom'
import './index.css'
import logo from './logo.svg'
import './App.css'
import Home from './components/home'
import Movie from './components/movie'
import Music from './components/music'

class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {}
  }

  render() {
    return (
      //当启用HashRouter 把跟组件包裹起来地址栏会出现# 这个时候hashRouter 就起作用了
      <HashRouter>
        //外部的跟组件包裹说明要使用路由
        <div>
          <h1> 网站的根组件 </h1>
          <hr />
          <Link to="/home">首页</Link>
          <Link to="/movie">电影</Link>
          <Link to="/music">音乐</Link> //相当于vue 的router-link
          <hr />
          <Route path="/home" component={Home} />
          //配置路由标签
          //相当于 配置组件 在react 中没有view 视图标签 而是把 route 当成一个占位符
          <Route path="/movie" component={Movie} />
          <Route path="/music" component={Music} />
        </div>
      </HashRouter>
    )
  }
}

export default App
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

1.2 路由传递参数

  1. 默认情况下 路由中的规则是模糊匹配的,如果路由可以按头部分匹配成功就可以展示组件。如果需要精确匹配,在 Route 上添加 exact

  2. 如果要从路由匹配规则中提取参数使用需要使用 props.match.params。属性名

     <Link to="/movie/top250/10">电影</Link>
         <Route exact path="/movie/:type/:id" component={Movie} />
              <h2>movie{this.props.match.params.id}</h2>
    //简单写法
    this.state={
        routerParams:props.match.params
    }
    <h2>movie{this.state.routerParams.id}</h2>
    
    1
    2
    3
    4
    5
    6
    7
    8

1.3 browerRouter

基本使用

import React, { Component } from 'react'
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'

const Index = () => <h2>Home</h2>

const About = () => <h2>About</h2>

const User = () => <h2>User</h2>

const Header = () => {
  return (
    <div>
      <nav>
        <ul>
          <li>
            <Link to="/home">Home</Link>
          </li>
          <li>
            <Link to="/about">About</Link>
          </li>
          <li>
            <Link to="/user">User</Link>
          </li>
        </ul>
      </nav>
    </div>
  )
}
const AppRouter = () => {
  return (
    <div>
      <Router>
        <Header />
        <Route path="/home" exact component={Index} />
        <Route path="/about" component={About} />
        <Route path="/user" component={User} />
      </Router>
    </div>
  )
}
export default AppRouter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

exact

代表 browerRouter 的精确匹配

forceRefresh

控制 react-router 跳转(history push)的时候刷新页面或不刷新页面 true 刷新 false 不刷新只有在不支持 HTML5 history API 的浏览器中使用此功能。

basename: string

所有位置的基准 URL。如果你的应用程序部署在服务器的子目录,则需要将其设置为子目录。

getUserConfirmation: func

用于确认导航的函数,默认使用 window.confirm。例如,当从 /a 导航至 /b 时,会使用默认的 confirm 函数弹出一个提示,用户点击确定后才进行导航,否则不做任何处理。译注:需要配合 <Prompt> 一起使用。

keyLength: number

location.key 的长度,

1.4 路由的内置参数使用

四个内置的参数 match history location

import React from 'react'
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'

const Index = () => <h2>Home</h2>

const About = () => <h2>About</h2>

const User = ({ match }) => <h3>{match.params.id}</h3>

const Users = ({ match }) => (
  <div>
    <h2>Users</h2>
    <ul>
      <li>
        <Link to={`${match.url}/component`}>component</Link>
      </li>
      <li>
        <Link to={`${match.url}/props-v-state`}>props-v-state</Link>
      </li>
      <li>
        <Link to={`${match.url}/state-v-sda`}>state-v-sda</Link>
      </li>
    </ul>

    <Route path={`${match.path}/:id(component|props-v-state|state-v-sda)`} component={User} />
    <Route
      exact
      path={match.path}
      render={() => {
        return <h3> 请选择一个user</h3>
      }}
    />
  </div>
)

const HeaderLinks = () => (
  <div>
    <nav>
      <ul>
        <li>
          <Link to="/home">Home</Link>
        </li>
        <li>
          <Link to="/about">About</Link>
        </li>
        <li>
          <Link to="/users">User</Link>
        </li>
      </ul>
    </nav>
  </div>
)

const AppRouter = () => (
  <div>
    <Router>
      <HeaderLinks />
      <Route path="/home" component={Index} />
      <Route path="/about" component={About} />
      <Route path="/users" component={Users} />
    </Router>
  </div>
)

export default AppRouter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

==match 中的数据==

  • path用于匹配的路径
  • url当前用来匹配的路径 也就是 link 跳转过来的路径
  • **params **传递过来的参数
  • **isExact **是否是精确匹配
  • 可以使用 字符串拼接的方式来进行路由的配置 {$match.url} {$match.path} 已经${match.params} 获取参数
  • ${match.path}/:id(component|props-v-state|state-v-sda) 说明 id 值匹配 component 或者 props-v-state 或者 state-v-sda 字段名 如果是其他字段名称则不匹配。

==history==

  • length
  • action
  • location
  • createhref

==location== 当前路由的访问参数

  • pathname 匹配的路径
  • search 搜索语句
  • hash 匹配字符的 hash
  • state 放的是路由的访问状态 {from:{}}来源路由的访问状态
  • key 关键字普配

==staticContext==

1.5 使用路由跳转 以及 withRoute 高级路由 和 私有路由组件使用

import React from 'react'
import 'bootstrap/dist/css/bootstrap.css'
import { BrowserRouter as Router, Route, Link, Redirect, withRouter } from 'react-router-dom'

let Auth = {
  isLogin: false,
  changeAuth(cb) {
    this.isLogin = true
    console.log('login')
    console.log('object', this.isLogin)
    setTimeout(cb, 100)
  },
  siginout(cb) {
    this.isLogin = false
    console.log('logout')
    setTimeout(cb, 100)
  }
}
const AuthButton = ({ history }) =>
  Auth.isLogin ? (
    <div>
      <h3> 欢迎登录</h3>
      <button
        onClick={() => {
          Auth.siginout(() => {
            history.push('/')
          })
        }}
      >
        登出
      </button>
    </div>
  ) : (
    <div>
      <h3>你还没有登录哦</h3>
    </div>
  )
const WithAuthButton = withRouter(AuthButton) //高级路由

const NavLinks = () => (
  <ul className="nav">
    <li>
      <Link to="/public">public page </Link>
    </li>
    <li>
      <Link to="/protected">protected page</Link>
    </li>
  </ul>
)
const PagePublic = () => (
  <div>
    <h1>public page</h1>
  </div>
)
const PageProtected = () => (
  <div>
    <h1>PageProtected page</h1>
  </div>
)
class Login extends React.Component {
  state = {
    //设置默认状态时不要跳转
    redirectToRefer: false
  }
  login = () => {
    Auth.changeAuth(() => {
      this.setState({
        //状态设置为跳转到来源组件
        redirectToRefer: true
      })
    })
  }
  render() {
    console.log(this.props.location, '72')
    let { from } = this.props.location.state || { from: { pathname: '/' } } //从 state 中取出来源路由地址  如果没有则设置默认值
    let { redirectToRefer } = this.state
    if (redirectToRefer) {
      //判断需要是否跳转到来源处
      return <Redirect to={from} /> //跳转到来源处
    } else
      return (
        //返回一个渲染的组件  登录按钮
        <div>
          <p>你必须要登录才能访问</p>
          <button onClick={this.login}>登录</button>
        </div>
      )
  }
}
//定义私有路由组件
const PrivateRouter = ({ component: Component, ...rest }) => {
  //使用参数分解赋值
  return (
    <Route //返回一个路由
      {...rest} //传递剩余的参数
      render={props => {
        //获取到props参数 此时router  会自动把 router的四个内置参数传递到 props 中
        console.log(props.location) //这里可以看到
        return Auth.isLogin ? ( //判读是否登录了
          <Component {...props} /> //登录了进行渲染组件
        ) : (
          <Redirect //没有登录跳转到 默认组件
            to={{
              //TO内部放一个对象 进行跳转 state 会覆盖到新的组件内部location的state 上
              pathname: '/login',
              state: {
                from: props.location
              }
            }}
          />
        )
      }}
    />
  )
}
const AppRouter = () => (
  <Router>
    <>
      <WithAuthButton />
      <NavLinks />
      <Route path="/public" component={PagePublic} />
      <Route exact path="/login" component={Login} />
      <PrivateRouter path="/protected" component={PageProtected} />
      //私有路由 包裹后 传递 需要渲染的组件和 访问的路由参数
    </>
  </Router>
)

export default AppRouter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
  1. withRoute 用处 可以让一个绝缘的组件内部接受到外部的 location 以及 match 等等属性,也就是把 router 的内置属性设置到 props 中

    没有包装的情况下
    {label: "home", to: "/home", children: "Home"}
    children: "Home"
    label: "home"
    to: "/home"
    __proto__: Object
    包装的情况下
    {label: "about", to: "/about", children: "about", history: {}, location: {},}
    
    1
    2
    3
    4
    5
    6
    7
    8

    通常用在 1.redux 的高阶组件 connect 通信感知 2 需要操作 history 操作路由

  2. 条件进行渲染组件

  3. 路由跳转后 router 的内置属性可以在 props 中可以拿到

  4. redirect 可以上 to 属性可以是一个字符串,直接跳转,也可以接受一个对象 跳转到 pathname 处,state 内部可以设置状态 state 内部的 from 代表来源位置

import React from 'react'
import 'bootstrap/dist/css/bootstrap.css'
import { BrowserRouter as Router, Route, Link, Redirect, withRouter } from 'react-router-dom'
const CustomLink = props => {
  let isActive = props.to === props.location.pathname //是否和当前的路由相同
  console.log('isActive', isActive)
  return (
    //分别设置背景颜色
    <Link style={{ background: isActive ? 'red' : 'black' }} className={isActive ? 'active' : ''} to={props.to}>
      {props.children}
    </Link>
  )
}
const WithCustomLink = withRouter(CustomLink) //高级组件封装 封装之后拿到location属性
const Home = () => <h1>Home</h1>
const About = () => <h1>About</h1>
const AppRouter = () => {
  return (
    <Router>
      <>
        <ul className="nav nav-pills">
          <li role="presentation">
            <WithCustomLink label="home" to="/home">
              Home
            </WithCustomLink>
          </li>
          <li role="presentation">
            <WithCustomLink label="about" to="/about">
              about
            </WithCustomLink>
          </li>
        </ul>
        <Route path="/home" component={Home} />
        <Route path="/about" component={About} />
      </>
    </Router>
  )
}

export default AppRouter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

1.7 实现阻止页面跳转 prompt

  • 1 when 接受一个 boolean 类型 什么时候阻止页面跳出当前路由
  • message 跳出后提示什么
import React from 'react'
import 'bootstrap/dist/css/bootstrap.css'
import { BrowserRouter as Router, Route, Link, Prompt } from 'react-router-dom'

const One = () => <h1>One</h1>
const Two = () => <h1>Two</h1>
class Home extends React.Component {
  state = {
    isBlock: false
  }

  render() {
    return (
      <div>
        {/* <Prompt when={this.state.isBlock} message="你确定要离开么" /> */} 第一种方式
        <Prompt //第二种使用方式
          when={this.state.isBlock}
          message={location => {
            console.log(location) //{pathname: "/one", search: "", hash: "", state: undefined, key: "9s91ak"}
            if (location.pathname.startsWith('/one')) {
              return `Are you sure you want to go to ${location.pathname}?`
            }
          }}
        />
        <form
          onSubmit={e => {
            e.preventDefault()
            this.setState({
              isBlock: false
            })
          }}
        >
          <p>{this.state.isBlock ? 'block' : 'no'}</p>
          <input
            name="username"
            type="text"
            onChange={e => {
              this.setState({ isBlock: e.target.value.length > 0 })
            }}
          />
          <button className="btn btn-primary" type="submit">
            提交
          </button>
        </form>
      </div>
    )
  }
}
const AppLinks = () => (
  <ul className="nav nav-pills">
    <li role="presentation">
      <Link to="/home">Form</Link>
    </li>
    <li role="presentation">
      <Link to="/one">one</Link>
    </li>
    <li role="presentation">
      <Link to="/two">two</Link>
    </li>
  </ul>
)

const AppRoutes = () => (
  <nav>
    <Route path="/one" component={One} />
    <Route path="/two" component={Two} />
    <Route path="/home" component={Home} />
  </nav>
)

const AppRouter = () => {
  return (
    <Router>
      <AppLinks />
      <AppRoutes />
    </Router>
  )
}

export default AppRouter

//可以和 <Router  getUserConfirmation={getConfirmation} > 配合使用
const getConfirmation = (message, callback) => {
    const allowTransition = window.confirm(message)
    console.log('你确定要离开么')
    callback(allowTransition)
  }
在点击了confirm 之后会触发这个函数  这个函数在message 之后触发 不长使用有BUG
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

1.8 处理 404 使用switch

import React from 'react'
import 'bootstrap/dist/css/bootstrap.css'
import { BrowserRouter as Router, Route, Link, Prompt, Redirect, Switch } from 'react-router-dom'

const AppLinks = () => (
  <ul className="nav nav-pills">
    <li role="presentation">
      <Link to="/"> Form </Link>
    </li>
    <li role="presentation">
      <Link to="/oldMatch"> old match </Link>
    </li>
    <li role="presentation">
      <Link to="/willMatch"> willMatch </Link>
    </li>
    <li role="presentation">
      <Link to="/willNotMatch"> will not Match </Link>
    </li>
    <li role="presentation">
      <Link to="/alseo/asda/asdf/asd"> also not match </Link>
    </li>
  </ul>
)

const AppRoutes = () => (
  <div>
    <Switch>
      //在于Switch匹配使用的时候要配合关键字exact 来使用
      <Route path="/" exact component={Home} />
      <Redirect from="/oldMatch" to="/willMatch" /> //from to
      <Route path="/willMatch" component={WillMatch} />
      <Route component={NotFound} />
    </Switch>
  </div>
)
const Home = () => <h1>Home</h1>
const WillMatch = () => <h1>WillMatch</h1>

const NotFound = () => <h1>NotFound</h1>

const AppRouter = () => {
  return (
    <Router>
      <AppLinks />
      <AppRoutes />
    </Router>
  )
}

export default AppRouter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
  • switch 匹配到第一个路由 Route 之后就会发挥该路由,所以最好使用精确匹配

  • 当没有匹配到的时候最后一个使用 404 无匹配的

1.9 递归路径

import React from 'react'
import 'bootstrap/dist/css/bootstrap.css'
import { BrowserRouter as Router, Route, Link, Prompt, Redirect, Switch, withRouter } from 'react-router-dom'

const PEEPS = [
  { id: 0, name: 'Michelle', friends: [1, 2, 3] },
  { id: 1, name: 'Sean', friends: [0, 3] },
  { id: 2, name: 'Kim', friends: [0, 1, 3] },
  { id: 3, name: 'David', friends: [1, 2] }
]
const Person = ({ match }) => {
  const persion = findfriend(match.params.id)
  console.log('match', match)

  let friends = []
  if (persion) {
    let fiendsID = persion.friends

    friends = fiendsID.map((item, index) => {
      return findfriend(item)
    })
  } else {
    friends = PEEPS
  }

  return (
    <div>
      <h3>{persion.name} friends</h3>
      <ul>
        {friends.map(item => (
          <li key={item.id}>
            <Link to={`${match.url}/${item.id}`}>{item.name}</Link>
          </li>
        ))}
      </ul>
      <Route path={`${match.url}/:id`} component={Person} />
    </div>
  )
}

const findfriend = id => PEEPS.find(p => p.id == id)

const AppRouter = () => {
  return (
    <Router>
      <Switch>
        <Redirect from="/" exact to="/0" />
        <Route path="/:id" component={Person} />
// 或者 <Persion match={{params:{id:0},url:""}}> 自己构早Match参数
      </Switch>
    </Router>
  )
}
export default AppRouter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

1.10 其他的路由列表方式

const routes = [
  {
    path: '/',
    exact: true,
    sidebar: () => <div>home!</div>,
    main: () => <h2>Home</h2>
  },
  {
    path: '/bubblegum',
    sidebar: () => <div>bubblegum!</div>,
    main: () => <h2>Bubblegum</h2>
  },
  {
    path: '/shoelaces',
    sidebar: () => <div>shoelaces!</div>,
    main: () => <h2>Shoelaces</h2>
  }
]
//使用
const LeftRoutes = () => (
  <div>
    {routes.map(route => {
      return <Route path={route.path} key={route.path} exact={route.exact} component={route.sidebar} />
    })}
  </div>
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

1.11

1.11 进行模糊匹配

可以使用 switch 于:参数 这样模糊动态匹配

1.12 参数传递

路由发生跳转时我们可能需要携带一些参数。

(1)props.params

指定一个 path ,然后指定通配符可以携带参数到指定的 path

<Route path='/user/:name' component={UserPage}></Route>
1

跳转 UserPage 页面时,可以这样写:

//link方法
<Link to="/user/sam">用户</Link>
//push方法
this.props.history.push("/user/sam");
1
2
3
4

在 UserPage 页面中通过 this.props.params.name 获取值。

上面的方法可以传递一个或多个值,但是每个值的类型都是字符串,没法传递一个对象。如果要传的话可以将 json 对象转换为字符串,传递过去之后再将 json 字符串转换为对象。

let data = {id:3,name:sam,age:36};
data = JSON.stringify(data);
let path = '/user/${data}';

//在页面中获取值时
let data = JSON.parse(this.props.params.data);
1
2
3
4
5
6
(2)query

query 方式可以传递任意类型的值,但是页面的 url 也是由 query 的值拼接的,url 很长且是明文传输。

//定义路由
<Route path='/user' component={UserPage}></Route>

//数据定义
let data = {id:3,name:sam,age:36};
let path = {
    pathname: '/user',
    query: data,
}

//页面跳转
<Link to={path}>用户</Link>
this.props.history.push(path);

//页面取值
let data = this.props.location.query;
let {id,name,age} = data;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
(3)state

state 方式类似于 post,依然可以传递任意类型的数据,而且可以不以明文方式传输。

//定义路由
<Route path='/user' component={UserPage}></Route>

//数据定义
let data = {id:3,name:sam,age:36};
let path = {
    pathname: '/user',
    state: data,
}

//页面跳转
<Link to={path}>用户</Link>
this.props.history.push(path);

//页面取值
let data = this.props.location.state;
let {id,name,age} = data;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

2 路由的实现

2.1 路由实现

//实现HashROuter组件
import React, { Component } from 'react'
import PropTypes from 'prop-types'

export default class HashRouter extends Component {
  static childContextTypes = {
    location: PropTypes.object //变成所有后代组件都可以使用的属性
    // history: PropTypes.object,
    // match: PropTypes.object,
  }
  constructor(props) {
    super(props)
    this.state = {}
  }
  getChildContext() {
    return {
      location: {
        //获取url上面的HASH
        pathname: window.location.hash.slice(1) || '/'
      }
    }
  }
  componentWillMount() {
    window.location.hash = window.location.hash || '/'
    let render = () => {
      //
      this.setState({}) //控制页面重绘,强制页面刷新
    }
    window.addEventListener('hashchange', render) //给页面的hash变化增加一个监听事件 是页面进行重绘
  }

  render() {
    return this.props.children
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//实现 Route组件
import React, { Component } from 'react'
import PropTypes from 'prop-types'

export default class Router extends Component {
  static contextTypes = {
    location: PropTypes.object
  }
  constructor(props) {
    super(props)
    this.state = {}
  }

  render() {
    let { path, component: RenderComponent } = this.props //使用时传递进来的参数
    // /movie
    let { pathname } = this.context.location //router 传递过来的context 参数
    console.log('pathname', pathname)
    if (path === pathname || pathname.startsWith(path)) {
      //进行比较  如果相同进行重绘
      return <RenderComponent location={this.context.location} />
    }
    return null //不同则不处理
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
使用
let Movie = () => (
  <div>
    <h1>电影</h1>
  </div>
)
let Music = () => (
  <div>
    <h1>音乐</h1>
  </div>
)
let Home = () => (
  <div>
    <h1>Home</h1>
  </div>
)
class App extends Component {
  constructor(props) {
    super(props)
    this.state = {}
  }
  render() {
    return (
      <HashRouter>
        <div>
          <section>
            <Route path="/movie" component={Movie} /> //传递path 和component 过去
            <Route path="/music" component={Music} />
            <Route path="/home" component={Home} />
          </section>
        </div>
      </HashRouter>
    )
  }
}
export default App
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import React, { Component } from 'react'
import PropTypes from 'prop-types'
export default class Link extends Component {
  static contextTypes = {
    history: PropTypes.object //接受history
  }
  render() {
    // return <a href={'#' + this.props.to}> {this.props.children} </a>
    return (
      //接受to的连接地址 推送到history 中  在router 组件页面可以监控到hash的变化 进行页面跳转
      <a onClick={() => this.context.history.push(this.props.to)} href="javascript:;">
        {this.props.children}
      </a>
    )
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

2.3 基于 path-to-regexp 实现参数正则

swich

redrict

protect

自定义菜单

2.4 route 渲染组件的三种方式

  1. 使用 component
  2. 使用 render 内部包含一个函数 render 只有在路由匹配后才会执行
  3. 使用 children 无论路由匹配或不匹配都会执行

render={一个函数}

<	Route {...rest} render={props=>{
 localStorage.getItem('login')?<Component {...props}/> :<Redirect to={{pathname:'login',state:{from:location.pathname}}}>
 }}/>
1
2
3