React router的Route應用


Route 是 React Router中用於配置路由信息的組件,每當有一個組件需要根據 URL 決定是否渲染時,就需要創建一個 Route。

react-router 中的很多特性都與 React 保持了一致,比如它的聲明式組件、組件嵌套,當然也包括 React 的狀態機特性。

1.path

每個Route都需要一個path屬性,path屬性是一個url,當URL匹配一個Route時,這個Route中定義的組件就會被渲染出來。

2.Route渲染組間的方式

(1)Component

component的值是一個組件,當URL和Route匹配時,Component屬性定義的組件就會被渲染。

<Route path="/mycom" component={MyCom} >

(2)Render

Render 值是一個函數,這個函數返回一個React元素。這種方式方便地為待渲染的組件傳遞額外的屬性。

<Route path=‘/mycom’  render={(props) => {

 <MyCom {…props} data={extraProps} /> //MyCom 組件接收了一個額外的data屬性

}}>

</Route>

(3)children

Children的值也是一個函數,函數返回要渲染的React元素。與前面不同是,無論是否匹配成功,children返回的組件都會被渲染。匹配不成功時,match屬性為null。

<Route path="/myCom" render={(props) => {

 <div className={props.match ? 'active' : ''}>

   <Foo {…props} data={extraProps} />

 </div>

}}

</Route>

如果Route匹配當前URL,待渲染元素的根節點div的class將設置成active.

3.多級路由

在路由里面繼續寫路由,掛載組件,就可以實現多級路由。路由嵌套實現。

<Route path=‘/myCom’ component={myCom}>
  <Route path=‘/myCom/sonCom’ component={SonCom}></Route>
</Route>

如果多級路由嵌套的層次太深,那我們寫子路由的path就會特別麻煩,所以可以這樣:

<Route path=‘/mycom’  render={(props) => {
  <Route path={`${props.match.path}/sonCom`} component={SonCom} /> }}>
</Route>

Match是從props解構出來,match.path就是我們當前這個路由的路徑,這樣不管嵌套多深,都可以寫上一級的路由

4.動態傳參

/foodlist/:id,傳過去的值就在路由掛載組件的props中,props里有個match, match中有個params, 注意:props只在路由掛載的組件才有

<Route path=‘/foodlist/:id’ component={MyCom} />

MyCom 組件的props中就可以獲取到id

可以在一個組件中用 this.props.history.push(“/path”, {name: “hellow”}), 來進行傳參,傳過去的值在props.location.state中

5.withRouter

一個典型的高階組件,如果我們既想實現點擊跳轉,又不想用Link的a標簽,我們可以用withRouter給我們吐出來一個實現點擊跳轉路由的組件。 Eg.

import { withRouter } from 'react-router-dom’; //使用自定義的組件: <CustomNavLink to="/food">food</CustomNavLink> <CustomNavLink to="/wiki">wiki</CustomNavLink> <CustomNavLink to="/profile">profile</CustomNavLink> //給自定義組件實現點擊功能: const CustomNavLink = withRouter(class EnhenceCustomNavLink extends Component { render () { return ( <li onClick={this.goto.bind(this)}> { this.props.location.pathname === this.props.to ? '>' + this.props.children : this.props.children } </li> ) } goto () { this.props.history.push(this.props.to) } })

假如你的組件沒有路由信息,你可以使用withRouter(component)將這個組件包起來,props里面就有路由信息了。

 

這里我們順便了解下前端路由的兩種模式:Hash模式和History模式

1、Hash 模式:

 這里的 hash 就是指 url 尾巴后的 # 號以及后面的字符。Hash 也稱作錨點,用來做頁面的定位,可以使對應的id的元素顯示在可視區域內。

Hash值的變化不會導致瀏覽器向服務器發出請求,而且hash改變會觸發hashchange事件,瀏覽器的前進和后退也能對其進行控制,在html5的history出現前,基本就是使用hash來實現前段路由的。

window.location.hsah = 'qq' //設置url的hash,會在當前url后加上#qq

var hash = window.location.hsah //qq

Window.addEventListener('hashchange', function() {

 //監聽hash變化,點擊瀏覽器的前進后退會觸發
)

 

2, History模式

已經有 hash 模式了,而且 hash 能兼容到IE8, history 只能兼容到 IE10,為什么還要搞個 history 呢?

首先,hash 本來是拿來做頁面定位的,如果拿來做路由的話,原來的錨點功能就不能用了。其次,hash 的傳參是基於 url 的,如果要傳遞復雜的數據,會有體積的限制,而 history 模式不僅可以在url里放參數,還可以將數據存放在一個特定的對象中。

window.history.pushState(state, title, url)
// state:需要保存的數據,這個數據在觸發popstate事件時,可以在event.state里獲取
// title:標題,基本沒用,一般傳 null
// url:設定新的歷史記錄的 url。新的 url 與當前 url 的 origin 必須是一樣的,否則會拋出錯誤。url可以是絕對路徑,也可以是相對路徑。
/*如 當前url是 https://www.baidu.com/a/,執行history.pushState(null, null, './qq/'),則變成 https://www.baidu.com/a/qq/,執行history.pushState(null, null, '/qq/'),則變成 https://www.baidu.com/qq/ */

window.history.replaceState(state, title, url)
// 與 pushState 基本相同,但這是修改當前歷史記錄,而 pushState 是創建新的歷史記錄

window.addEventListener(“popstate”, funbction(){
  // 監聽瀏覽器前進后退事件,pushState 與 replaceState 方法不會觸發     
});

window.history.back() // 后退
window.history.forward()// 前進
window.history.go(1) //前進一步,-2為后退兩步,window.history.length可以查看當前歷史堆棧中頁面的數量

history 模式改變 url 的方式會導致瀏覽器向服務器發送請求,需要在服務器端做處理:如果匹配不到任何靜態資源,則應該始終返回同一個 html 頁面。

 

我們再順便了解下:用戶訪問的URL后面加入# 號的知識

1. #號的含義:

#號代表網頁中的一個位置,# 號后面的內容就是該位置的一個標記,eg.

http://www.example.com/index.html#print

訪問該地址,瀏覽器頁面會自動滾動到print 位置,print顯示在可視區域

//為頁面指定位置的有兩種方式:
1)加錨點 <a name=“print”></a> 
 (2)<div id=“print”></div>

2.Http請求不包括#部分

比如訪問上面的鏈接,實際發出的請求是:

GET /index.html HTTP/1.1

Host: www.example.com

#號后面的任何字符,都會被解析為位置標志符,比如:

http://www.example.com/?color=#fff

實際發出的請求是:

GET /?color= HTTP/1.1
Host: www.example.com

這並不是我們所期望的,可以對#號轉義 #轉為23%

http://www.example.com/?color=23%fff

 

3.改變網頁的#號部分,不會觸發網頁的重載

http://www.example/com/index.html#location1
http://www.example.com/index.html#location2 
//改變#號后面的內容,不會重新觸發服務器的請求,也就是#號后面的內容對服務器端沒影響

4.改變#號后面的內容,可以修改瀏覽器的訪問歷史

每一次改變#后的部分,都會在瀏覽器的訪問歷史中增加一個記錄,使用"后退"按鈕,就可以回到上一個位置。

5.window.location.hash 可以讀到#號后面的內容

來判斷網頁是否發生了變化,給window.location.hash賦值時,就是增加了一條瀏覽器的歷史訪問記錄

6. onhashchange 是HTML5增加的可以監聽hash改變的接口:

window.onhashchange = func;
<body onhashchange="func();">
window.addEventListener("hashchange", func, false);

對於不支持onhashchange的瀏覽器,可以用setInterval監控location.hash的變化。

7.Google抓取#的機制

默認情況下,Google的網絡蜘蛛忽視URL的#部分。

如果你希望Ajax生成的內容被瀏覽引擎讀取,那么URL中可以使用"#!",Google會自動將其后面的內容轉成查詢字符串_escaped_fragment_的值。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM