首頁 >web前端 >js教程 >React中路由使用詳解

React中路由使用詳解

php中世界最好的语言
php中世界最好的语言原創
2018-05-24 14:20:112612瀏覽

這次帶給大家React中路由使用詳解,React中路由使用的注意事項有哪些,下面就是實戰案例,一起來看一下。

路由

透過 URL 對應到對應的功能實現,React 的路由使用要先引入 react-router.js。 
注意:  
react-router 4.0 以上的版本和 3.0 及以下的版本有很大的差別,本教學使用的是 3.0.2 的版本,後續會更新 4.0 以上版本的教學。 
在使用 npm 安裝時預設安裝最新版本,如果安裝的版本是最新的,而使用上使用的是 3.0 版本的用法,則會報錯。 
所以在 npm 安裝時要指定版本 npm install react-router@3.0.2 --save-dev

路由背景-SPA

傳統的前端基本上都是透過頁面之間跳轉來實現各功能模組的切換,這種做法會導致一個項目下來存在大量的html 頁面,而且每個頁面都有一大堆的靜態資源文件需要引入,在性能一直被垢病。後來有了隨著ajax 的普及,還有jQuery 對ajax 的封裝後的便捷使用,開發者會大量的使用ajax 來加載一個html 頁面到當前頁面的某個容器當中來實現無刷新加載,但依然沒有解決大量存在html 頁面和每個頁面載入大量的靜態資源檔案而導致效能上的問題。隨著行動網路的普及,行動端對頁面載入的效能要求和流量的限制越來越高,所以主流的前端框架都往 SPA 方向靠齊。
SPA,Single Page Application 的縮寫,單頁面應用,其目的是整個應用程式只有一個html 頁面,結合構建webpack 的統一打包思想,把所有靜態資源文件打包成一個js 文件,在唯一的一個html頁面引用,從而真正意義上實作一個html 文件,一個js 文件完成一個應用程式的構想。
SPA 優化了靜態載入的效能,但一個應用程式還是有很多的功能模組,功能模組之間的切換,就變成了元件之間的切換,所以到目前為止基本上主流的前端框架都會有路由和元件兩個概念,而且實現思想都是一致的。

路由引用與使用

//es5
var {Router, Route, hashHistory, Link, IndexRoute, browserHistory} = require("react-router");

//es6
import {Router, Route, hashHistory, Link, IndexRoute, browserHistory} from 'react-router';

//es5 和 es6 的使用都是一样的
<Link to="/">Root</Link>
<Router>
    <Route path=&#39;/&#39; component={RootComponent}/>
</Router>

//使用 `<script>` 标签 
<script src="../js/ReactRouter.js"></script>
<ReactRouter.Link to="/">Root</ReactRouter.Link>
<ReactRouter.Router>
    <ReactRouter.Route path=&#39;/&#39; component={RootComponent}/>
</ReactRouter.Router>

路由元件與屬性

Link

  • #用於路由之間跳轉,功能等同於a 標籤。

  • 屬性 to 等同於 a 標籤的 href

  • <Link to="/page">page</Link>,作用等同於<a href="#/page ">page</a>

Router

  • 是最外層的路由元件,整個 Application 只有一個。

  • 屬性history 有兩個屬性值:

    • hashHistory 路由將透過URL的hash部分(#)切換,建議使用。

    • <Router history={hashHistory}> 對應的URL 形式類似example.com/#/some/path

    • browserHistory 這種情況需要對伺服器改造。否則使用者直接向伺服器要求某個子路由,會顯示網頁找不到的404錯誤。

    • <Router history={browserHistory}> 對應的 URL 形式類似 example.com/some/path。

Route 元件的屬性

  • #Route 是元件Router 子元件,可以透過嵌套route 來實現路由嵌套。

  • 屬性 path:指定路由的匹配規則,這個屬性是可以省略的,這樣的話,不管路徑是否匹配,總是會載入指定元件。

  • 屬性 component:指當 URL 對應到路由的符合規則時會渲染對應的元件。

  • <Route path="/" component={RootComponent}/> 當URL 為example.com/#/ 時會渲染元件RootComponent

  • <Route path="/page1" component={Page1Component}/> 當URL 為example.com/#/page1 時會渲染元件Page1Component

基本用法

import React from 'react'
import ReactDOM from 'react-dom'
import {Router, hashHistory, browserHistory} from 'react-router'

const html = (
    <ul>
        <li><Link to="/">Root</Link></li>
        <li><Link to="/page">page</Link></li>
    </ul>
)

class RootComponent extends React.Component{
    render(){
        return (
            <p>
                <h1>RootComponent</h1>
                {html}
            </p>
        )       
    }
}

class PageComponent extends React.Component{
    render(){
        return (
            <p>
                <h1>PageComponent</h1>
                {html}
            </p>
        )       
    }
}

ReactDOM.render(
    <Router history={hashHistory}>
        <Route path=&#39;/&#39; component={RootComponent}/>
        <Route path=&#39;/page&#39; component={PageComponent}/>
    </Router>,
    document.getElementById('app')
)

效果預覽

路由參數

  • 路由的參數傳遞是透過Route 元件的path 屬性來指定的。

  • 參數值可透過 this.props.params.paramName 來取得。

  • :paramName

    • #符合URL的一個部分,直到遇到下一個/、?、 #為止。

    • <Route path="/user/:name">

    • 符合 URL:/#/user/sam,參數 sam 為必須存在。

    • this.props.params.name 的值為 sam。

import React from 'react'
import ReactDOM from 'react-dom'
import {Router, hashHistory, browserHistory} from 'react-router'

class UserComponent extends React.Component{
    render(){
        return (
            <p>
                <h3>UserComponent 单个参数 </h3>
                <p>路由规则:path='/user/:username'</p>
                <p>URL 映射:{this.props.location.pathname}</p>
                <p>username:{this.props.params.username}</p>
            </p>
        )       
    }
}
ReactDOM.render(
    <Router history={hashHistory}>
        <Route path=&#39;/user/:username&#39; component={UserComponent}/>
    </Router>,
    document.getElementById('app')
)
  • (:paramName)

    • 表示URL的这个部分是可选的。

    • <Route path="/order(/:orderid)">

    • 匹配 URL:/#/order,this.props.params.orderid 获取的值为 undefined。

    • 匹配 URL:/#/order/001,this.props.params.orderid获取参数的值为 001。

import React from 'react'
import ReactDOM from 'react-dom'
import {Router, hashHistory, browserHistory} from 'react-router'

class UserComponent extends React.Component{
    render(){
        return (
            <p>
                <h3>OrderComponent 可选参数 </h3>
                <p>路由规则:path='/order(/:orderid)'</p>
                <p>URL 映射:{this.props.location.pathname}</p>
                <p>orderid:{this.props.params.orderid}</p>
            </p>
        )       
    }
}
ReactDOM.render(
    <Router history={hashHistory}>
        <ReactRouter.Route path=&#39;/order(/:orderid)&#39; component={UserComponent}/>
    </Router>,
    document.getElementById('app')
)
  • *.*

    • 匹配任意字符,直到模式里面的下一个字符为止。匹配方式是非贪婪模式。

    • <Route path="/all1/*.*">

    • this.props.params 获取的参数为一个固定的对象: {splat: [*, *]}

    • 匹配 URL:/all1/001.jpg,参数为 {splat: ['001', 'jpg']}

    • 匹配 URL:/all1/001.html,参数为 {splat: ['001', 'html']}

  • *

    • 匹配任意字符,直到模式里面的下一个字符为止。匹配方式是非贪婪模式。

    • <Route path="/all2/*">

    • this.props.params 获取的参数为一个固定的对象: {splat: '*'}

    • 匹配 URL:/all2/,参数为 {splat: ''}

    • 匹配 URL:/all2/a,参数为 {splat: 'a'}

    • 匹配 URL:/all2/a/b,参数为 {splat: 'a/b'}

  • **

    • 匹配任意字符,直到下一个/、?、#为止。匹配方式是贪婪模式。

    • <Route path="/**/*.jpg">

    • this.props.params 获取的参数为一个固定的对象: {splat: [**, *]}

    • 匹配 URL:/all3/a/001.jpg,参数为 {splat: ['a', '001']}

    • 匹配 URL:/all3/a/b/001.jpg,参数为 {splat: ['a/b', '001']}

效果预览

IndexRoute

当访问一个嵌套路由时,指定默认显示的组件

AppComponent.js

import React from 'react'

export default class AppComponent extends React.Component{
    render(){
        return <p>{this.props.children}</p>
    }
}

LoginComponent.js

import React, {Component} from 'react'

export default class LoginComponent extends Component{
    login(){}
    render(){
        return <h1>Login</h1>
    }
}

HomeComponent.js

import React, {Component} from 'react'

export default class HomeComponent extends Component{
    login(){}
    render(){
        return <h1>Home</h1>
    }
}

Router.js

import React from 'react'
import {Route, IndexRoute} from 'react-router'

import AppComponent from '../components/app/app'
import HomeComponent from '../components/home/home'
import LoginComponent from '../components/login/login'

const routes = (
    <Route path="/" component={AppComponent}>
        <IndexRoute component={HomeComponent} />
        <Route path="login" component={LoginComponent} />
        <Route path="home" component={HomeComponent} />
    </Route>
)

export default routes;
  • 如果没有加IndexRoute,则在访问 http://localhost/#/ 时页面是空白的

  • 访问 http://localhost/#/login 才会显示内容

  • 加上 IndexRoute,在访问http://localhost/#/时会默认渲染HomeComponent

模块化

可利用组件Router的属性routes来实现组件模块化

router.js

import React from 'react'
import ReactDOM from 'react-dom'

import {Route, Router, IndexRoute, hashHistory} from 'react-router'

import AppComponent from '../components/app/app'
import HomeComponent from '../components/home/home'
import LoginComponent from '../components/login/login'

const routes = (
    <Route path="/" component={AppComponent}>
        <IndexRoute component={HomeComponent} />
        <Route path="login" component={LoginComponent} />
        <Route path="home" component={HomeComponent} />
    </Route>
)

ReactDOM.render(
    <Router history={hashHistory} routes={routes} />,
    document.getElementById('app')
)

编程式导航

  • 普通跳转 this.props.router.push('/home/cnode')

  • 带参数跳转this.props.router.push({pathname: '/home/cnode', query: {name: 'tom'}})

路由钩子函数

每个路由都有enterleave两个钩子函数,分别代表用户进入时和离开时触发。

onEnter

进入路由/home前会先触发onEnter方法,如果已登录,则直接next()正常进入目标路由,否则就先修改目标路径replace({ pathname: 'login' }),再next()跳转。

let isLogin = (nextState, replace, next) => {
    if(window.localStorage.getItem('auth') == 'admin'){
        next()
    } else {
        replace({ pathname: 'login' })
        next();
    }
    
}
const routes = (
    <Route path="/" component={AppComponent}>
        <Route path="login" component={LoginComponent} />
        <Route path="home" component={HomeComponent} onEnter={isLogin}/>
    </Route>
)

onLeave

对应的setRouteLeaveHook方法,如果return true则正常离开,否则则还是停留在原路由

import React from 'react'
import {Link} from 'react-router'

export default class Component1 extends React.Component{
    componentDidMount(){
        this.props.router.setRouteLeaveHook(
            this.props.route,
            this.routerWillLeave
        )
    }
    routerWillLeave(){
        return '确认要离开?'
    }
    render(){
        return (
            <p>
                <Link to="/login">Login</Ling>
            </p>
        )
    }
}

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

PromiseA+的实现步骤详解

react实现选中li高亮步骤详解

以上是React中路由使用詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn