React学习——路由

路由

官网 中文官网
vue-router和react-router的区别:

vue-router react-router
分离式 嵌套式
排他性(只有一个路由被渲染) 包容性(多路由渲染)
静态路由 动态路由

安装
React Router被拆分成三个包:
react-router
react-router-dom
react-router-native

结构
BrowserRouter|HashRouter

  • 根组件(App)
    • NavLink|Link
    • Route
    • Redirect
      • 子组件
        • NavLink|Link
        • Route

BrowserRouter

import React from 'react';
import ReactDom,{render} from 'react-dom';
import {BrowserRouter, HashRouter, Route} from 'react-router-dom'
import Default from "./layouts/Default";

render(
  <BrowserRouter>
    <Route component={Default}/>
  </BrowserRouter>,
  document.getElementById('root')
);

Route
path:(string object)路由匹配路径。没有path属性的Route总是会匹配。
exact:(boolean)为true时,全局匹配(/home),多个Route可以同时匹配和渲染。
component:(function)匹配地址的时候React的组件才回被渲染。

 <Route path="/home" component={Home}/>

Link
to:(string) | {pathname,search,hash}要跳转的路径或地址
replace:(boolean) 是否替换历史记录

let {history,location,match}=props
<Link to={match.url+'/001'}/>
<Link to={`${match.url}/002?a=1&b=2`}/>
<Link to={{pathname:match.url+'/003',search:'?a=11&b=12',hash:'#a1'}}

NavLink
to:(string object)跳转的路径或地址
replace:(boolean) 是否替换历史记录
activeClassNamestring:当元素被选中时,设置选中样式,默认为active
activeStyle:(object)当元素被选中时,设置选中样式
exact:(Boolean)严格匹配

<NavLink activeClassName="default__nav--active" to="/home">首页</NavLink>

Switch
该组件用来渲染匹配地址的第一个Route或者Redirect,仅渲染一个路由,排他性路由,默认全匹配 (场景:侧边栏和面包屑,引导选项卡等
location:(string object)
children:(node)

Redirect
from:(string) 来自
to:(string object) 去向
push:(boolean) 添加历史记录
exact:(boolean) 严格模式
sensitive:(boolean) 区分大小写

参数数据传递

<Switch>
    <Redirect from="/" to="/home"/>
</Switch>

404

  <Route component={NoPage}/>  //总是会匹配

编程式跳转

history.push('/user?a=1&b=2')
history.push({pathname:'/user',search:'?a=11&b=22'})
history.replace({pathname:'/user',search:'?a=111&b=222'})
history.go(-1)

例子

import React from 'react';

export default class Home extends React.Component{
  render(){
    return (
      <div className="home">
        <h3>首页</h3>
        <button onClick={()=>this.props.history.push('/login')}>跳转</button>
        <button onClick={()=>this.props.history.push({pathname:'/goods/4',search:'a=3&b=4'})}>跳转2</button>
      </div>
    )
  }
}

非路由跳转组件

不是所有组件会通过路由跳转,也需要抓取路由上下文时,解决方案

  1. 通过路由跳转
  2. 通过属性传递
  3. 通过withRouter包装
import {withRouter} from 'react-router-dom'
class App extends Component{}
export default withRouter(App)

例子

import React from 'react';
import {withRouter} from 'react-router-dom';

class Child extends React.Component {
  render() {
    return (
      <div className="Child">
        <h3>Child</h3>
      </div>
    )
  }
}

export default withRouter(Child)

前置授权路由
需要自定义路由,具体为,自定义一个组件,代替Route,其内部根据条件返回一个Route 组件指向目标组件,或者Route的render函数内部判断加载目标,最后组件树关系为:switch>自定义组件>Route>目标组件

<Auth path="/goods" component={Goods} />
<Auth path="/user" component={User} />

export default class Auth extends React.Component{

  state={
    hasSendAuth:false,
    auth:false,
    data:{}
  };

  async componentDidMount(){
    let res = await axios({url:'/data/user.json'})
    console.log('数据回来了')
    this.setState({
      auth:res.data.auth,
      hasSendAuth:true,
      data:res.data.data
    })
  }

  render(){
    // console.log('渲染了',this.props)  //包含了path,component的一个传入
    let {component:Component} = this.props;//目标组件
    if (!this.state.hasSendAuth) return null;

    return <Route render={props=>(//...props 目标组件需要用到的路由信息
      this.state.auth ?
        <Component {...props} data={this.state.data} /> :// 数据预载
        <Redirect to="/login" />
    )}/>

  }
}

后置守卫

// reg.jsx
import { Prompt } from 'react-router-dom'
<Prompt
  when={this.state.isBlocking}
  message={location=>...}
/>

message: 后面可以跟简单的提示语,也可以跟函数,函数是有默认参数的。
when: when的属性值为true时防止跳转;


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章