react-router

路由用來分發(fā)請求,前端是顯示頁面的,所以它的路由是在找component,后端是提供服務(wù)的,它的路由是在找controller

【5種路由方式】

  • BrowserRouter:瀏覽器的路由方式,在開發(fā)中最常使用。
  • HashRouter:在路徑前加入#號成為一個哈希值。Hash模式的好處- 是,再也不會因為我們刷新而找不到我們的對應(yīng)路徑了。
  • MemoryRouter:不存儲history,所有路由過程保存在內(nèi)存里,不能進(jìn)行前進(jìn)后退,因為地址欄沒有發(fā)生任何變化。
  • NativeRouter:經(jīng)常配合ReactNative使用,多用于移動端。
  • StaticRouter:設(shè)置靜態(tài)路由,需要和后臺服務(wù)器配合設(shè)置,比如設(shè)置服務(wù)端渲染時使用。

【BrowserRouter】

import { BrowserRouter } from 'react-router-dom'

<BrowserRouter
  basename={optionalString}
  forceRefresh={optionalBool}
  getUserConfirmation={optionalFunc}
  keyLength={optionalNumber}
>
  <App/>
</BrowserRouter>

1、basename: 當(dāng)前位置的基準(zhǔn) URL。如果頁面部署在服務(wù)器的二級(子)目錄,需要將basename設(shè)置到此子目錄。 正確的 URL 格式是前面有一個前導(dǎo)斜杠,但不能有尾部斜杠

<BrowserRouter basename="/calendar"/>

2、getUserConfirmation:當(dāng)導(dǎo)航需要確認(rèn)時執(zhí)行的函數(shù)。默認(rèn)使用 window.confirm

// 使用默認(rèn)的確認(rèn)函數(shù)
const getConfirmation = (message, callback) => {
  const allowTransition = window.confirm(message)
  callback(allowTransition)
}
<BrowserRouter getUserConfirmation = {getConfirmation} />

3、forceRefresh:當(dāng)設(shè)置為 true 時,在導(dǎo)航的過程中整個頁面將會刷新。 只有當(dāng)瀏覽器不支持 HTML5 的 history API 時,才設(shè)置為 true。

const supportsHistory = 'pushState' in window.history
<BrowserRouter forceRefresh={!supportsHistory}/>

4、keyLengthlocation.key的長度。默認(rèn)是 6。

<BrowserRouter keyLength={12}/>

5、BrowserRouter只能渲染單一子元素。

【Route】
  Route是react-router中最重要的組件,用來匹配請求并渲染相應(yīng)組件。
  1、path 路徑的匹配值,可以包括以下幾種特殊符號

:paramName – 匹配一段位于 /、? 或 # 之后的 URL。 命中的部分將被作為一個參數(shù)。
() – 在它內(nèi)部的內(nèi)容被認(rèn)為是可選的
* – 匹配任意字符(非貪婪的)直到命中下一個字符或者整個 URL 的末尾,并創(chuàng)建一個 splat 參數(shù)

例子如下所示:

<Route path="/hello/:name">         // 匹配 /hello/michael 和 /hello/ryan
<Route path="/hello(/:name)">       // 匹配 /hello, /hello/michael 和 /hello/ryan
<Route path="/files/*.*">           // 匹配 /files/hello.jpg 和 /files/path/to/hello.jpg

[注意]Route組件不能像普通組件一樣,以屬性的形式傳遞參數(shù),但可以通過path屬性來傳遞,但一定要區(qū)分router后面的:_id或:id。

'/category/:_id'

??2、component 要顯示的組件

import { BrowserRouter as Router, Route } from 'react-router-dom'

<Router>
  <div>
    <Route exact path="/" component={Home}/>
    <Route path="/news" component={NewsFeed}/>
  </div>
</Router>

??3、render 函數(shù)中return的值就是要顯示的內(nèi)容

<Route path="/home" render={() => <div>Home</div>}/>

??4、childrenrender的區(qū)別在于,不管有沒有匹配,都想顯示的內(nèi)容

const ListItemLink = ({ to, ...rest }) => (
  <Route path={to} children={({ match }) => (
    <li className={match ? 'active' : ''}>
      <Link to={to} {...rest}/>
    </li>
  )}/>
)

 [注意]component/render/children只能三個選一個使用

【匹配規(guī)則】
??默認(rèn)地,路由進(jìn)行寬松匹配。在下面例子中,路由匹配到/one時,既顯示組件A,也顯示組件B。

<Route  path="/one" component={A}/>
<Route  path="/one/two" component={B}/>

如果要進(jìn)行確切匹配,則需要添加exact屬性。這樣,路由匹配到/one時,只顯示組件A。

<Route  exact path="/one" component={A}/>
<Route  path="/one/two" component={B}/>

還有一種是嚴(yán)格匹配,即斜杠也必須嚴(yán)格匹配。下面例子中,路由匹配到/one/時,會顯示組件A,但匹配到/one時,什么都不會顯示

<Route  strict path="/one/" component={A}/>

[注意]嚴(yán)格匹配并不是確切匹配。下面例子中,路由匹配到/one時,即顯示組件A,也顯示組件B

<Route  strict path="/one" component={A}/>
<Route  path="/one/two" component={B}/>

如果要確切匹配,則需要

<Route  exact strict path="/one" component={A}/>

但是,一般地,strict屬性很少使用

【屬性】
  Route默認(rèn)攜帶三個props:包括matchlocationhistory
  如果使用component,則使用this.props來獲取,如果是render,則在回調(diào)函數(shù)中使用參數(shù)(props)=>{}來獲取
??1、match
  match包括以下屬性:

params 鍵值對
isExact 是否確切匹配
path 路徑中設(shè)置的值
url URL中的path值

??2、location
  location中包含如下屬性:
  [注意]直接訪問location,而不是訪問history.location

{
  key: 'ac3df4', // not with HashHistory!
  pathname: '/somewhere'
  search: '?some=search-string',
  hash: '#howdy',
  state: {
    [userDefined]: true
  }
}

通過Link傳遞的state,可以在location中獲取到
[注意]剛開始時,或者直接刷新瀏覽器,state是沒有值的,只有跳轉(zhuǎn)到該鏈接時,state才有值。再后來,刷新也有值了。
??3、history
  history包含如下屬性:

length: history棧的長度
action: 當(dāng)前的action
location: 當(dāng)前的location對象

??history包含如下方法:

push()
goBack() = go(-1)
goForward() = go(1)
go() 跳轉(zhuǎn)到 history棧中的哪個enter
replace(path, [state]) 替換history棧中的當(dāng)前entry
push(path, [state])  添加當(dāng)前entry到history棧中

【Redirect】
  Redirect將頁面導(dǎo)航到新位置,新位置將覆蓋history棧中的當(dāng)前位置,類似于服務(wù)器端的重定向(HTTP 3xx)。
  to屬性可以是一個字符串,表示跳轉(zhuǎn)的地址。

<Route exact path="/" render={() => (
  loggedIn ? (
    <Redirect to="/dashboard"/>
  ) : (
    <PublicHomePage/>
  )
)}/>

??to屬性也可以是一個對象

<Redirect to={{
  pathname: '/login',
  search: '?utm=your+face',
  state: { referrer: currentLocation }
}}/>

??push屬性為true時,表示添加新記錄到history棧中,而不是替換當(dāng)前記錄。

<Redirect push to="/somewhere/else"/>

【Link】
  Link是對a標(biāo)簽的封裝,提供無刷新的頁面跳轉(zhuǎn)。Link標(biāo)簽主要的屬性是to屬性。

1、一般地,to是一個字符串

<Link to="/about">關(guān)于</Link>

2、也可以寫成對象的形式

<Link to={{
  pathname: '/courses',
  search: '?sort=name',
  hash: '#the-hash',
  state: { fromDashboard: true }
}}/>

[注意]在Link里的子組件或同組件的點(diǎn)擊事件,最好加上阻止默認(rèn)行為和阻止冒泡。

<Link>
  <div onclick={}></div>
</Link>
<Link onclick={}>

【NavLink】
  NavLink相對于Link來說,增加了一些樣式屬性
  activeClassName表示被匹配的a標(biāo)簽的樣式名;activeStyle表示被匹配的a標(biāo)簽的樣式。

<NavLink
  to="/faq"
  activeClassName="selected"
>FAQs</NavLink>
<NavLink
  to="/faq"
  activeStyle={{
    fontWeight: 'bold',
    color: 'red'
   }}
>FAQs</NavLink>

[注意]linkhistory.push都不支持指向外網(wǎng)地址,如果要跳轉(zhuǎn)到外網(wǎng),則需要使用window對象下的location對象

【Switch】
  渲染Route或Redirect匹配到的第一個子元素

<Switch>
  <Route exact path="/" component={Home}/>
  <Route path="/about" component={About}/>
  <Route path="/:user" component={User}/>
  <Route component={NoMatch}/>
</Switch>

[注意]switch必須直接包括Route,中間不可包含div,否則不生效
跳轉(zhuǎn)。

如果在實(shí)現(xiàn)邏輯跳轉(zhuǎn),可使用如下代碼實(shí)現(xiàn):

// utils/history.js
import createBrowserHistory from 'history/createBrowserHistory'
const customHistory = createBrowserHistory()
export default customHistory

引用如下:

import  history  from '@/utils/history'
// 跳轉(zhuǎn)到首頁
history.push('/')

要特別注意的是,如果使用utils/history.js,需要使用Router history={history},而不是BrowserRouter
  因為全局只能有一個history實(shí)例。 使用import { BrowserRouter as Router }語句,會自動創(chuàng)建一個history實(shí)例的,相當(dāng)于有兩個實(shí)例,則會出現(xiàn)URL發(fā)生變化,刷新頁面后,頁面才跳轉(zhuǎn)的情況。

import { Router, Route, Switch, Redirect } from 'react-router-dom'
import history from '@/utils/history'

<Router history={history}>
  <Switch>
    <Route path="/login" component={Login} />
    <Route path="/" render={props => {if (sessionStorage.getItem('token') && sessionStorage.getItem('user')) {return <Home {...props} />
        }
        return <Redirect to="/login" />
      }} />
  </Switch>
</Router>

【傳參】
  history.push方法也可以攜帶參數(shù),方法如下

history.push({
  pathname: '/about',
  search: '?the=search',
  state: { some: 'state' }
})
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容