第十一節(jié):React路由:react-router認(rèn)識(shí)與基本使用

1. React Router的理解

React的路由根據(jù)項(xiàng)目的不同使用不同的路由庫,web應(yīng)用主要使用react-routerreact-router-dom

react-routerreact-router-dom的區(qū)別

  1. react-rotuer 核心庫,提供了一些核心的api,但是沒有提供dom操作進(jìn)行跳轉(zhuǎn)的api
  2. react-router-dom擴(kuò)展了核心庫,提供了一些操作DOM的api,
  3. web應(yīng)用正常使用react-router-dom就可以了, 因?yàn)樗约和瑯右蕾?code>react-router

2. 路由組件認(rèn)識(shí)

2.1 路由組件的認(rèn)識(shí)

在react中和vue不同的是,路由不是配置的文件,而是組件, 正常的組件嵌套使用

在React router中通常使用的組件有三種

  1. 路由器組件: 如BrowserRouter(history模式) 和 HashRouter(hash模式)
  2. 路由匹配組件: Route 和 Switch 組件
  3. 導(dǎo)航組件: Link 和 NavLink 組件
2.2. 相關(guān)API
<BrowserRouter>    // 路由器組件
<HashRouter>       // 路由器組件
<Route>            // 顯示路由組件,嵌套在路由器組件中
<Switch>           // 路由切換組件,如果配置成功多個(gè)路由也只會(huì)顯示第一個(gè)
<Link>             // 路由導(dǎo)航組件
<NavLink>          // 路由導(dǎo)航組件
<Redirect>         // 路由重定向組件

3. 路由組件的使用

3.1 下載路由組件庫
$ npm install react-router-dom --save

## or

$ yarn add react-router-dom

3.2 路由器組件的使用
3.2.1 路由器組件說明:
  1. 每一個(gè)React Router應(yīng)用程序的核心都應(yīng)該是路由器組件
  2. react-router-dom提供了BrowserRouterHashRouter
  3. BrowserRouter采用常規(guī)路徑顯示方式的history路由顯示模式
  4. HashRouter采用錨點(diǎn)顯示的hash路由顯示模式
3.2.2 BrowserRouter組件的使用

基本使用

采用history路由模式顯示路由

示例代碼:

// 導(dǎo)入路由器
import {BrowserRouter} from "react-router-dom"

// 使用路由器組件嵌套根組件APP
ReactDOM.render(
    <BrowserRouter>
        <App />
    </BrowserRouter>,
    document.getElementById('root')
);

為什么使用BrowserRouter嵌套根組件APP呢?

其實(shí)沒有說一定要嵌套APP根組件, 只是導(dǎo)航組件和路由組件必須嵌套的路由器組件中才會(huì)有效,否則就會(huì)報(bào)錯(cuò)

因此只要在你是用的導(dǎo)航組件和路由組件外嵌套即可, 嵌套根組件表示整個(gè)應(yīng)用任何位置都可以是使用路由組件

BrowserRouter路由器采用history前端路由模式, 因此在路徑顯示上沒有#

如下:

http://localhost:3000/goods

3.2.3 HashRouter組件的使用

HashRouter采用hash模式的前端路由, 以此會(huì)出現(xiàn)#/home

示例代碼:

// 導(dǎo)入路由器
import {HashRouter} from "react-router-dom"

// 使用路由器組件嵌套根組件APP
ReactDOM.render(
    <HashRouter>
        <App />
    </HashRouter>,
    document.getElementById('root')
);

路徑顯示結(jié)果:

http://localhost:3000/#/goods

3.2.4 路由器的別名使用

有的時(shí)候會(huì)將路由器組件在使用import導(dǎo)入是修改別名

示例代碼如下

// 將HashRouter 路由器組件修改為別名Router使用
import {HashRouter as Router} from "react-router-dom"

// 使用路由器組件的別名
ReactDOM.render(
        <Router>
            <App />
        </Router>,
    document.getElementById('root')
);

3.3 路由匹配組件的使用
3.3.1 路由匹配組件Route的使用

Route組件用來控制路徑對(duì)應(yīng)顯示的組件

說明:

  1. Route組件基本的兩個(gè)屬性,一個(gè)是path,一個(gè)是component
  2. path屬性表示用來匹配路徑,黨路徑匹配成功后展示component的內(nèi)容
  3. component屬性值是將來用于展示的組件

示例代碼如下:

import {Route, Link} from 'react-router-dom'
// 導(dǎo)入組件
import Home from "./components/Home"
import Goods from "./components/Goods"
import About from "./components/About"

// App組件
function App() {
    return (
        <div className="App">

            {/* 
                Route路由展示組件
                當(dāng)path的值和路徑匹配成功后顯示component對(duì)應(yīng)的組件
            */} 
            <Route path="/home" component={Home}/>
            <Route path="/goods" component={Goods}/>
            <Route path="/about" component={About}/>
        </div>
    );
}

示例代碼說明:

  1. 上面的示例代碼,在默認(rèn)打開是不顯示任何組件內(nèi)容,
  2. 默認(rèn)打開的路徑為/所以Route中的路徑都匹配不成功
  3. 如果希望/路由對(duì)應(yīng)的顯示內(nèi)容也為首頁, 就可能會(huì)如下寫法

示例代碼

import {Route, Link} from 'react-router-dom'
import Home from "./components/Home"
import Goods from "./components/Goods"
import About from "./components/About"

function App() {
    return (
        <div className="App">

            <Route path="/home" component={Home}/>
            <Route path="/goods" component={Goods}/>
            <Route path="/about" component={About}/>
            <Route path="/" component={Home}/>
        </div>
    );
}

示例代碼說明:

  1. 示例的本意是希望/home/路徑都展示首頁組件,/表示默認(rèn)打開顯示首頁
  2. 但是示例真實(shí)的情況是,無論/home,/goods,/about路徑,最后一個(gè)/Route都會(huì)展示
  3. 這樣就導(dǎo)致了頁面會(huì)同時(shí)渲染兩個(gè)組件,
3.3.2 Switch組件

Switch組件說明:

  1. Switch組件用于包裹Route組件, 表示只會(huì)渲染第一個(gè)與路徑配置成功的Route組件對(duì)應(yīng)的內(nèi)容
  2. 如果有兩個(gè)組件都匹配路徑都成功,也只會(huì)顯示第一個(gè),
  3. 或者顯示Redirect重定向組件內(nèi)容
  4. 也就是說路徑只會(huì)匹配到第一個(gè)成功的Route就不會(huì)在下匹配其他Route組件了,
  5. 如果不使用Switch組件,則會(huì)將所有Route組件都匹配一下,所有匹配成功的組件都會(huì)展示

示例代碼如下

import {Route, Link,Switch} from 'react-router-dom'
import Home from "./components/Home"
import Goods from "./components/Goods"
import About from "./components/About"

function App() {
    return (
        <div className="App">

            <Switch>
                <Route path="/home" component={Home}/>
                <Route path="/goods" component={Goods}/>
                <Route path="/about" component={About}/>
                <Route path="/" component={Home}/>
            </Switch>
        </div>
    );
}

示例說明:

  1. 這樣就解決了之前存在的問題
  2. 當(dāng)路由為/時(shí)匹配最后一個(gè)Route,因此展示首頁
  3. 如果當(dāng)路由匹配到/goods,展示商品頁,此時(shí)會(huì)中斷匹配, 也就不會(huì)匹配到/,此時(shí)也不會(huì)再次展示一個(gè)首頁組件
3.4 導(dǎo)航組件
3.4.1 導(dǎo)航組件說明:
  1. 導(dǎo)航組件的作用是用來點(diǎn)擊跳轉(zhuǎn)路由,為LinkNavLink
  2. Link組件和NavLink組件的區(qū)別在于時(shí)候會(huì)添加額外的類名
  3. Link組件在跳轉(zhuǎn)路由時(shí),當(dāng)前活躍的導(dǎo)航不會(huì)添加任何類名
  4. NavLink跳轉(zhuǎn)路由,會(huì)給當(dāng)前活躍的導(dǎo)航添加額外的類名,可以利用類名添加不同的樣式
3.4.2 Link組件的使用

Link組件有一個(gè)to屬性, 有來指定跳轉(zhuǎn)到那個(gè)路由

示例代碼如下:

import {Route, Link,Switch} from 'react-router-dom'

import Home from "./components/Home"
import Goods from "./components/Goods"
import About from "./components/About"

function App() {
    return (
        <div className="App">
            <Link to="/home">首頁</Link>
            <Link to="/goods">商品頁</Link>
            <Link to="/about">關(guān)于頁</Link>

            <Switch>
                <Route path="/home" component={Home}/>
                <Route path="/goods" component={Goods}/>
                <Route path="/about" component={About}/>
                <Route path="/" component={Home}/>
            </Switch>

        </div>
    );
}

示例說明:

  1. Link標(biāo)簽會(huì)被編譯為a標(biāo)簽
  2. to屬性表示當(dāng)你點(diǎn)擊時(shí),跳轉(zhuǎn)到那個(gè)路由上
  3. 但是不會(huì)添加任何額外的類名

控制臺(tái)Elements里展示的內(nèi)容

<div class="App">
    <a href="#/home">首頁</a>
    <a href="#/goods">商品頁</a>
    <a href="#/about">關(guān)于頁</a>
    <div>這是首頁</div>
</div>

因此沒發(fā)確定當(dāng)前那個(gè)導(dǎo)航對(duì)應(yīng)的路由是活躍狀態(tài)

3.4.3 NavLink 組件的使用

NavLink會(huì)給當(dāng)前活躍的路徑導(dǎo)航添加額外的類名, 利用添加給導(dǎo)航添加不同的樣式

因此NavLink組件使用相對(duì)較多

示例代碼:

import {Route, NavLink,Switch} from 'react-router-dom'

import Home from "./components/Home"
import Goods from "./components/Goods"
import About from "./components/About"

function App() {
    return (
        <div className="App">
            <NavLink to="/home">首頁</NavLink>
            <NavLink to="/goods">商品頁</NavLink>
            <NavLink to="/about">關(guān)于頁</NavLink>

            <Switch>
                <Route path="/home" component={Home}/>
                <Route path="/goods" component={Goods}/>
                <Route path="/about" component={About}/>
                <Route path="/" component={Home}/>
            </Switch>

        </div>
    );
}

示例顯示后的Elements結(jié)果

<div class="App">
    <a href="#/home">首頁</a>
    <a href="#/goods" aria-current="page" class="active">商品頁</a>
    <a href="#/about">關(guān)于頁</a><
    div>商品頁面</div>
</div>

此時(shí)會(huì)發(fā)現(xiàn),當(dāng)前展示的是商品頁面, 對(duì)應(yīng)的導(dǎo)航會(huì)有一個(gè)額外的類名activ

因此可以利用active給當(dāng)前顯示的導(dǎo)航添加不同的樣式

.active{
    color:red;
}

3.5 路由重定向組件的使用

路由重定向 Redirect 組件使用說明

  1. Redirect組件可以在所有路由都匹配不成功后,默認(rèn)跳轉(zhuǎn)展示的內(nèi)容,如訪問的路由不存在,展示首頁
  2. Redirect組件也可以在路由匹配成功后,驗(yàn)證權(quán)限, 不足的跳轉(zhuǎn)指定路由, 如登錄賬號(hào)不存在跳轉(zhuǎn)注冊(cè)

示例代碼:

import {Route, NavLink,Switch,Redirect} from 'react-router-dom'

import Home from "./components/Home"
import Goods from "./components/Goods"
import About from "./components/About"

function App() {
    return (
        <div className="App">
            <NavLink to="/home">首頁</NavLink>
            <NavLink to="/goods">商品頁</NavLink>
            <NavLink to="/about">關(guān)于頁</NavLink>

            <Switch>
                <Route path="/home" component={Home}/>
                <Route path="/goods" component={Goods}/>
                <Route path="/about" component={About}/>
                <Route path="/" component={Home}/>
                {/* 使用路由重定向, 當(dāng)路由匹配不成功時(shí),顯示首頁 */}
                <Redirect to="/home" />
            </Switch>

        </div>
    );
}

3.6 withRouter組件的使用
3.6.1 withRouter組建了解
  1. withRouter為高階組件,其實(shí)就是一個(gè)函數(shù),參數(shù)是一個(gè)組件, 返回值也是一個(gè)組件
  2. 正常的路由組件都能在props屬性接受和路由有關(guān)的match,location,history對(duì)象
  3. 如果是非路由組件不能在props屬性中獲取這些路由對(duì)象,如果需要在非路由組件中使用路由對(duì)象內(nèi)容
  4. 就需要給非路由組件嵌套一個(gè)WitchRouter高級(jí)組件,

因?yàn)?code>WitchRouter組件就是為了讓非路由組件也能訪問路由對(duì)象的高階組件

3.6.2 未使用withRouter

非路由組件中獲取props

export default class Header extends Component {

    render() {
        console.log(this.props);
        /*
       打印結(jié)果:
       {}
      */

        return (
            <h2>應(yīng)用的頭部</h2>
        );
    }
}

路由組件中獲取props

export default class Home extends Component {

    render() {
        console.log(this.props);
        /*
        打印結(jié)果:
            {
                history: {...},
                location:{...},
                match:{...},
            }
        */
        return (
            <div>
                這是首頁
            </div>
        );
    }
}

3.6.3 使用withRouter

使用withRouter執(zhí)行,傳入非路由組件

import React, { Component } from 'react';

// 引入高級(jí)組件
import { withRouter } from 'react-router-dom'
class Header extends Component {

    render() {
        console.log(this.props);
        /*
        打印結(jié)果:
            {
                history: {...},
                location:{...},
                match:{...},
            }
        */
        return (
            <h2>應(yīng)用的頭部</h2>
        );
    }
}

/*
 使用高級(jí)組件, withRouter的參數(shù)是Header組件,
 返回一個(gè)處理后的組件
*/
export default withRouter(Header)

此時(shí)非路由組建的props屬性中就可以獲取到路由組件才能獲取到的history,math,location對(duì)象

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容