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時防止跳轉;


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