三、React Router 5路由升略,路由傳參

一席揽、路由

1.1汗盘、 SPA的理解

1.單頁Web應(yīng)用(single page web application注祖,SPA)猾蒂。
2.整個(gè)應(yīng)用只有一個(gè)完整的頁面。
3.點(diǎn)擊頁面中的鏈接不會(huì)刷新頁面是晨,只會(huì)做頁面的局部更新肚菠。
4.數(shù)據(jù)都需要通過ajax請求獲取, 并在前端異步展現(xiàn)。

1.2罩缴、路由的理解

1.什么是路由?

1.一個(gè)路由就是一個(gè)映射關(guān)系(key:value)
2.key為路徑, value可能是function或component

2.路由分類

后端路由:
1蚊逢、理解: value是function, 用來處理客戶端提交的請求层扶。
2、注冊路由: router.get(path, function(req, res))
3时捌、工作過程:當(dāng)node接收到一個(gè)請求時(shí), 根據(jù)請求路徑找到匹配的路由, 調(diào)用路由中的函數(shù)來處理請求, 返回響應(yīng)數(shù)據(jù)
前端路由:
1怒医、瀏覽器端路由炉抒,value是component奢讨,用于展示頁面內(nèi)容。
2焰薄、注冊路由: <Route path="/test" component={Test}>
3拿诸、工作過程:當(dāng)瀏覽器的path變?yōu)?test時(shí), 當(dāng)前路由組件就會(huì)變?yōu)門est組件

一、React Router 5

react-router-dom的理解

1塞茅、react的一個(gè)插件庫亩码。
2、專門用來實(shí)現(xiàn)一個(gè)SPA應(yīng)用野瘦。
3描沟、基于react的項(xiàng)目基本都會(huì)用到此庫。

下載react-router-dom:

npm install --save react-router-dom

內(nèi)置組件
1鞭光、<BrowserRouter>:用于將應(yīng)用程序包裹在 HTML5 history API 的 <BrowserRouter> 中吏廉,使得 React Router 可以監(jiān)聽 URL 的變化,并且匹配當(dāng)前 URL 對應(yīng)的 Route 進(jìn)行渲染惰许。
2席覆、<HashRouter>:用于將應(yīng)用程序包裹在 hash history 的 <HashRouter> 中,適用于不支持 HTML5 history API 的環(huán)境汹买,如舊版瀏覽器或一些特殊環(huán)境佩伤。
3、<Route>:用于聲明路由規(guī)則晦毙,即指定路徑對應(yīng)的組件渲染內(nèi)容生巡。<Route> 根據(jù)當(dāng)前 URL 路徑匹配對應(yīng)的路徑規(guī)則,并渲染相關(guān)組件见妒。
4障斋、<Redirect>:用于在匹配到某個(gè)路徑時(shí)重定向到另一個(gè)路徑,可以用于處理一些特殊場景徐鹤,比如用戶訪問的舊路徑需要重定向到新路徑垃环。
5、<Link>:用于在應(yīng)用中創(chuàng)建導(dǎo)航鏈接返敬,點(diǎn)擊該鏈接后會(huì)更新 URL 而不會(huì)重新加載頁面遂庄,實(shí)現(xiàn)單頁應(yīng)用的導(dǎo)航功能。
6劲赠、<NavLink>:是 <Link> 的一個(gè)增強(qiáng)版本涛目,除了具有 <Link> 的功能外秸谢,還可以添加 activeClassName 和 activeStyle 等屬性,用于定義鏈接激活時(shí)的樣式霹肝。
7估蹄、<Switch>:用于包裹多個(gè) <Route> 組件,它會(huì)遍歷所有子 <Route> 組件沫换,并只渲染與當(dāng)前 URL 匹配的第一個(gè) <Route> 或 <Redirect> 組件臭蚁,避免多個(gè)路由同時(shí)匹配的問題

1.1、BrowserRouter 和 HashRouter 的區(qū)別

1.底層原理不一樣
??BrowserRouter使用的是H5的history API讯赏,不兼容IE9及以下版本垮兑。HashRouter使用的是URL的哈希值。
2.path表現(xiàn)形式不一樣
??BrowserRouter的路徑中沒有#,例如: localhost:3000/demo/test
??HashRouter的路徑包含#,例如: localhost:3000/#/demo/test
3.刷新后對路由state參數(shù)的影響
??(1).BrowserRouter沒有任何影響漱挎,因?yàn)閟tate保存在history對象中系枪。
??(2).HashRouter刷新后會(huì)導(dǎo)致路由state參數(shù)的丟失!!!

原生html中,靠<a>跳轉(zhuǎn) 不同的頁面
              <a href="./about.html">About</a>
              <a href="./home.html">Home</a>

在React中靠路由鏈接實(shí)現(xiàn)切換組件
首先我們把a(bǔ)bout.html和home.html改成兩個(gè)組件
然后引入 Link 和 Route 磕谅,通過<Route>注冊路由私爷,通過 <Link />進(jìn)行切換組件

import {HashRouter, Link , Route} from "react-router-dom";

hash路由模式
<HashRouter>
  跳轉(zhuǎn)路由
  <Link to="/about" />
  <Link to="/home" />
  注冊路由
  <Route path="/about" component={About}></Route>
  <Route path="/home" component={Home}></Route>
</HashRouter>

1.2、<NavLink>是<Link>的一個(gè)特定版本膊夹,會(huì)在匹配上當(dāng)前的url的時(shí)候給已經(jīng)渲染的元素添加參數(shù)衬浑,組件的屬性有:

  • activeClassName(string):設(shè)置選中樣式,默認(rèn)值為active
  • activeStyle(object):當(dāng)元素被選中時(shí)割疾,為此元素添加樣式
  • exact(bool):為true時(shí)嚎卫,只有當(dāng)導(dǎo)致和完全匹配class和style才會(huì)應(yīng)用
  • strict(bool):為true時(shí),在確定為位置是否與當(dāng)前URL匹配時(shí)宏榕,將考慮位置pathname后的斜線
  • isActive(func)判斷鏈接是否激活的額外邏輯的功能
    所以開發(fā)中一般使用<NavLink>

路由的基本使用

import { HashRouter, Route, NavLink } from "react-router-dom";
<HashRouter>
 跳轉(zhuǎn)路由
  <NavLink to="/about" />
  <NavLink to="/home" />
  注冊路由
  <Route path="/about" component={About}></Route>
  <Route path="/home" component={Home}></Route>
</HashRouter>

1.3拓诸、Switch和Redirect

當(dāng)我們注冊路由,注冊了同樣的路徑麻昼,渲染不同的路由組件奠支,當(dāng)跳轉(zhuǎn)路由的時(shí)候有兩個(gè)路由能匹配上就會(huì)出現(xiàn)兩個(gè)路由組件全部展示的情況,如下圖

  <Route path="/home" component={Home}></Route>
  <Route path="/home" component={Test}></Route>

正常來說一個(gè)路徑匹配一個(gè)路由抚芦,上圖明顯有問題倍谜,如果每個(gè)同樣的路徑匹配多個(gè)路由組件,如果我們要展示兩個(gè)路由組件為什么不把兩個(gè)路由組件合成一個(gè)組件呢叉抡,當(dāng)?shù)谝粋€(gè)路由組件匹配上以后尔崔,如果下面還有無數(shù)個(gè)相同路徑的路由組件,會(huì)匹配無數(shù)次路由會(huì)導(dǎo)致性能損耗褥民,所以一個(gè)路徑匹配一個(gè)路由季春。這個(gè)時(shí)候我們會(huì)使用Switch:Switch實(shí)現(xiàn)提高匹配效率的效果,匹配到第一個(gè)后面就不會(huì)匹配了

<Switch>
  <Route path="/about" component={About}></Route>
  <Route path="/home" component={Home}></Route>
  <Route path="/home" component={Test}></Route>
 一般寫在所有路由注冊的最下方消返,當(dāng)所有路由都無法匹配時(shí)载弄,跳轉(zhuǎn)到Redirect指定的路由
  <Redirect to="/about" />
</Switch>

路由的嚴(yán)格模式


如上圖耘拇,我們注冊的路由組件路徑和跳轉(zhuǎn)路由的開始的路徑能匹配上,就能正常展示路由組件的頁面宇攻,如下圖惫叛,跳轉(zhuǎn)的路徑是 /home/index,注冊路由的地址是 /home,因?yàn)樘D(zhuǎn)路徑前面的地址是 /home,默認(rèn)是模糊模式逞刷,所以成功匹配展示注冊路由組件
如果需要注冊的路由組件路徑和跳轉(zhuǎn)路由的開始的路徑完全一樣:

路由開啟嚴(yán)格匹配
嚴(yán)格模式不要隨便開啟嘉涌,這樣會(huì)影響二級(jí)路由
<Route exact path="/about" component={About}></Route>第一種方法,寫exact屬性就行
<Route exact={true} path="/home" component={Home}></Route>第二種方法亲桥,寫exact={true}

嵌套路由

這里是父組件洛心,正常寫路由就行
<Switch>
  <Route path="/about" component={About}></Route>
  <Route path="/home" component={Home}></Route>
  <Redirect to="/about" />
</Switch>

這里是子路由的組件固耘,子路由注冊的時(shí)候需要加上父組件的路徑
<Switch>
  <Route path="/home/news" component={News}/>//嵌套路由需要加上父路徑
  <Redirect to="/home/news"/>
</Switch>

React Router 5路由傳參

跳轉(zhuǎn)路由
 向路由組件傳遞params參數(shù) 
 <Link to={`/home/message/detail/${i.id}/${i.title}`}  children={i.title} />
 向路由組件傳遞search參數(shù)  
 <Link to={`/home/message/detail/?id=${i.id}&title=${i.title}`}  children={i.title} />
 向路由組件傳遞state參數(shù)  
  <Link to={{pathname: "/home/message/detail", state: {id:i.id,title:i.title}}}  children={i.title} />

注冊路由
 聲明接收params參數(shù)
 <Route path="/home/message/detail/:id/:title" component={Detail} />
 search參數(shù)無需聲明接收题篷,正常注冊路由即可
 <Route path="/home/message/detail" component={Detail} />
 state參數(shù)無需聲明接收,正常注冊路由即可
 <Route path="/home/message/detail" component={Detail} />

路由組件接受路由參數(shù)
 接收params參數(shù)
 const {id, title} = this.props.match.params;
 接收search參數(shù)
 import qs from "querystring";
 const {id, title} = qs.parse((this.props.location.search).slice(1));
 接收state參數(shù)
 const {id, title} = this.props.location.state || {};

接收search參數(shù)厅目,需要下載querystring  npm i querystring
querystring基本使用
import qs from "querystring";

let obj = { name: 'tom', age: 18}; //name=tom&age=18 key=value&key=value
console.log(qs.stringify(obj));

let str = 'carName=奔馳&price=199';
console.log(qs.parse(str));

路由跳轉(zhuǎn)模式push和replace
push(/path) 里面的path會(huì)進(jìn)入路由棧番枚,
replace(/path) 不會(huì),但是它里面的path會(huì)替換掉路由棧里最后一個(gè)路由

路由跳轉(zhuǎn)開啟replace模式损敷,默認(rèn)是push模式
<Link to={`/home/message/detail/${i.id}/${i.title}`} replace={true} children={i.title} />

編程式路由

通過按鈕觸發(fā)方法葫笼,方法里進(jìn)行路由跳轉(zhuǎn)
  <button onClick={() => this.pushShow(i)}>Push查看</button>
  <button onClick={() => this.replaceShow(i)}>Replace查看</button>

注冊路由
  接收params參數(shù)
  <Route path="/home/message/detail/:id/:title" component={Detail} />
  search參數(shù)無需聲明接收,正常注冊路由即可
  <Route path="/home/message/detail" component={Detail} />
  state參數(shù)無需聲明接收拗馒,正常注冊路由即可
  <Route path="/home/message/detail" component={Detail} />

跳轉(zhuǎn)路由
replaceShow = (i) =>{
    replace跳轉(zhuǎn)+攜帶params參數(shù)
    this.props.history.replace(`/home/message/detail/${i.id}/${i.title}`)
    
    replace跳轉(zhuǎn)+攜帶search參數(shù)
    this.props.history.replace(`/home/message/detail?id=${i.id}&title=${i.title}`)
    
    replace跳轉(zhuǎn)+攜帶state參數(shù)
    this.props.history.replace(`/home/message/detail`,{...i})
}
pushShow = (i) =>{
    push跳轉(zhuǎn)+攜帶params參數(shù)
    this.props.history.push(`/home/message/detail/${i.id}/${i.title}`)
    
    push跳轉(zhuǎn)+攜帶search參數(shù)
    this.props.history.push(`/home/message/detail?id=${i.id}&title=${i.title}`)
    
    push跳轉(zhuǎn)+攜帶state參數(shù)
    this.props.history.push(`/home/message/detail`,{...i})
}

路由組件接受路由參數(shù)
 接收params參數(shù)
 const {id, title} = this.props.match.params;
 接收search參數(shù)
 import qs from "querystring";
 const {id, title} = qs.parse((this.props.location.search).slice(1));
 接收state參數(shù)
 const {id, title} = this.props.location.state || {};
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末路星,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子诱桂,更是在濱河造成了極大的恐慌洋丐,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挥等,死亡現(xiàn)場離奇詭異友绝,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)肝劲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門迁客,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人辞槐,你說我怎么就攤上這事掷漱。” “怎么了榄檬?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵卜范,是天一觀的道長。 經(jīng)常有香客問我丙号,道長先朦,這世上最難降的妖魔是什么缰冤? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮喳魏,結(jié)果婚禮上棉浸,老公的妹妹穿的比我還像新娘。我一直安慰自己刺彩,他們只是感情好迷郑,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著创倔,像睡著了一般嗡害。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上畦攘,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天霸妹,我揣著相機(jī)與錄音,去河邊找鬼知押。 笑死叹螟,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的台盯。 我是一名探鬼主播罢绽,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼静盅!你這毒婦竟也來了良价?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤蒿叠,失蹤者是張志新(化名)和其女友劉穎明垢,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體栈虚,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡袖外,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了魂务。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片曼验。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖粘姜,靈堂內(nèi)的尸體忽然破棺而出鬓照,到底是詐尸還是另有隱情,我是刑警寧澤孤紧,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布豺裆,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏臭猜。R本人自食惡果不足惜躺酒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蔑歌。 院中可真熱鬧羹应,春花似錦、人聲如沸次屠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽劫灶。三九已至裸违,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間本昏,已是汗流浹背供汛。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留凛俱,地道東北人紊馏。 一個(gè)月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓料饥,卻偏偏與公主長得像蒲犬,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子岸啡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344

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