react路由
開始今天的話題之前,讓我們先來了解一下前端路由,Ajax誕生以后,解決了每次用戶操作都要向服務(wù)器端發(fā)起請求重刷整個(gè)頁面的問題,但隨之而來的問題是無法保存Ajax操作狀態(tài),瀏覽器的前進(jìn)后退功能也不可用,當(dāng)下流行的兩種解決方法是:
- hash, hash原本的作用是為一個(gè)很長的文檔頁添加錨點(diǎn)信息,它自帶不改變url刷新頁面的功能,所以自然而然被用在記錄Ajax操作狀態(tài)中了。
- history, 應(yīng)該說history是主流的解決方案,瀏覽器的前進(jìn)后退用的就是這個(gè),它是window對(duì)象下的,以前的history提供的方法只能做頁面之間的前進(jìn)后退,如下:
為了讓history不僅僅能回退到上一個(gè)頁面,還可以回到上一個(gè)操作狀態(tài)。HTML5新增了三個(gè)方法,其中兩個(gè)是在history對(duì)象里的:
history.go(number|URL)可加載歷史列表中的某個(gè)具體的頁面history.forward()可加載歷史列表中的下一個(gè) URLhistory.back()可加載歷史列表中的前一個(gè) URL
為了讓history不僅僅能回退到上一個(gè)頁面,還可以回到上一個(gè)操作狀態(tài)。HTML5新增了三個(gè)方法,其中兩個(gè)是在history對(duì)象里的:
history.pushState(state, title, url)
添加一條歷史記錄, state用于傳遞參數(shù),可以為空。title是設(shè)置歷史記錄的標(biāo)題,可以為空。url是歷史記錄的URL,不可以為空。history.replaceState(state, title, url)
將history堆棧中當(dāng)前的記錄替換成這里的url,參數(shù)同上。
還有一個(gè)事件在window對(duì)象下:
window.onpopstate()監(jiān)聽url的變化,會(huì)忽略hash的變化(hash變化有一個(gè)onhashchange事件),但是前面的兩個(gè)事件不會(huì)觸發(fā)它。
好了,到這里你大概猜到了單頁面應(yīng)用或者Ajax操作記錄狀態(tài)用的就是hash和h5增加的history API,這就是react-router-dom 擴(kuò)展的路由實(shí)現(xiàn),也是web應(yīng)用最常用的兩種路由。
react 路由
安裝
yarn add react-router-dom
基本路由
導(dǎo)入路由需要的組件
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
路由組件解釋
Router 總路由
link 路由導(dǎo)航
----to 切換的鏈接
Route 路由
----path 對(duì)應(yīng)鏈接
----component 對(duì)應(yīng)組件
簡單路由完整代碼
import React, { Component } from 'react';
import {BrowserRouter as Router,Route,Link} from 'react-router-dom'
// 導(dǎo)入子組件
class App extends Component {
render() {
return (
<div className="App" >
<Router>
<div> <Link to="/">首頁</Link> | <Link to="/about">關(guān)于</Link> </div>
<hr/>
<Route path="/" exact component={Home}></Route>
<Route path="/about" component={About}></Route>
</Router>
</div>
);
}
}
function Home(){
return (<h1>我是首頁</h1>);
}
function About(){
return (<h1>我是關(guān)于</h1>);
}
export default App;
路由的參數(shù)
01 定義指令 Link指令
<Link to="/produce/1">產(chǎn)品1</Link> |
<Link to="/produce/abc">產(chǎn)品abc</Link></div>
02 定義路由
<Route path="/produce/:id" component={Produce}></Route>
03 定義組件-獲取路由參數(shù)
function Produce({match}){
return (<h1>我是產(chǎn)品:{match.params.id}</h1>);
}
match 是組件默認(rèn)傳遞的參數(shù), match.paras 組件路由參數(shù)對(duì)象
出來match對(duì)象 還有 history對(duì)象和location對(duì)象
子路由
我們這里用Navlink 講解它比link 選中的時(shí)候多個(gè)一個(gè) active 的class
導(dǎo)入Navlink
import {BrowserRouter as Router,Route,Link,NavLink} from 'react-router-dom'
01 定義指令 Link指令
<NavLink to="/detail">詳情</NavLink>
02 定義主路由
<Route path="/detail" component={Detail}></Route>
03 編寫主路由
function Detail({location,match}){
return (
<div>
<div><NavLink to={match.url+'/arg'}>參數(shù)</NavLink> | <NavLink to={match.url+'/com'}>評(píng)論</NavLink> | </div>
<hr/>
<Route path={match.url+'/arg'} component={Arg}></Route>
<Route path={match.url+'/com'} component={Com}></Route>
</div>);
}
match.url 獲取當(dāng)前匹配的主路由地址
04 編寫子路由
function Arg(){
return (<h1>我是Arg </h1>);
}
function Com(){
return (<h1>我是com</h1>);
}
路由404配置 與Switch
Switch能讓匹配的路由唯一
01 導(dǎo)入Switch
import {BrowserRouter as Router,Route,Link,Switch,NavLink,Redirect} from 'react-router-dom'
02 定義路由
<Switch>
<Route path="/" exact component={Home}></Route>
<Route path="/about" component={About}></Route>
<Route path="/produce/:id" component={Produce}></Route>
<Route path="/detail" component={Detail}></Route>
<Route component={NoMatch}></Route>
</Switch>
定義404路由要寫到最后
03 編寫404路由
function NoMatch({location}){
return (<h1>頁面沒有找到{location.pathname}</h1>);
}
location 當(dāng)前的地址
pathname 當(dāng)了地址信息
重定向
我們需要寫一個(gè)默認(rèn)的子路由,這個(gè)時(shí)候可用重定向
01 導(dǎo)入重定向
import {
BrowserRouter as Router,
Route,
Link,
Switch,
NavLink,
Redirect
} from 'react-router-dom'
重新編寫 主路由
function Detail({location,match}){
return (<div>
<div><NavLink to={match.url+'/arg'}>參數(shù)</NavLink> | <NavLink to={match.url+'/com'}>評(píng)論</NavLink> | </div>
<hr/>
<Switch>
<Route path={match.url+'/arg'} component={Arg}></Route>
<Route path={match.url+'/com'} component={Com}></Route>
<Redirect from={match.url} to={match.url+'/arg'}/>
</Switch>
</div>);
}
from 是可以省略的
完整代碼
import React, { Component } from 'react';
import Child from './components/Child'
import {BrowserRouter as Router,Route,Link,Switch,NavLink,Redirect} from 'react-router-dom'
// 導(dǎo)入子組件
class App extends Component {
render() {
return (
<div className="App" >
<Router>
<div>
<NavLink to="/" exact>首頁</NavLink> |
<NavLink to="/about">關(guān)于</NavLink> |
<NavLink to="/produce/1">產(chǎn)品1</NavLink> |
<NavLink to="/produce/abc">產(chǎn)品abc</NavLink></div>|
<NavLink to="/detail">詳情</NavLink>
<hr/>
<Switch>
<Route path="/" exact component={Home}></Route>
<Route path="/about" component={About}></Route>
<Route path="/produce/:id" component={Produce}></Route>
<Route path="/detail" component={Detail}></Route>
<Route component={NoMatch}></Route>
</Switch>
</Router>
</div>
);
}
}
function Home(){
return (<h1>我是首頁</h1>);
}
function About({history}){
return (<h1>我是關(guān)于 <button onClick={()=>{history.go(-1)}}>返回</button> <button onClick={()=>{history.push("/")}}>首頁</button> </h1>);
}
function Produce({match}){
return (<h1>我是產(chǎn)品:{match.params.id}</h1>);
}
function NoMatch({location}){
return (<h1>頁面沒有找到{location.pathname}</h1>);
}
function Detail({location,match}){
return (<div>
<div><NavLink to={match.url+'/arg'}>參數(shù)</NavLink> | <NavLink to={match.url+'/com'}>評(píng)論</NavLink> | </div>
<hr/>
<Switch>
<Route path={match.url+'/arg'} component={Arg}></Route>
<Route path={match.url+'/com'} component={Com}></Route>
<Redirect from={match.url} to={match.url+'/arg'}/>
</Switch>
</div>);
}
function Arg(){
return (<h1>我是Arg </h1>);
}
function Com(){
return (<h1>我是com</h1>);
}
export default App;
組件的參數(shù)
function About({match,history,location}){
console.log(match,history,location)
return (<h1>我是about</h1>);
}
match 匹配的當(dāng)前路由
isExact: true ,//是否精確匹配
params:{}// 當(dāng)前路由的參數(shù)
path:{} //路由指定的path
url:{}// link 指定的鏈接地址
history當(dāng)前路由信息
go() 歷史記錄跳轉(zhuǎn)
goBack() 歷史記錄返回
goFoward() 前進(jìn)
length 歷史記錄的長度
push() 跳轉(zhuǎn) 有歷史記錄
replace() 跳轉(zhuǎn)沒有歷史記錄
location 地址信息
---hash #后面的參數(shù)
---pathname 當(dāng)前路由的地址
---search 問號(hào)后面的參數(shù)
location 同history的location 當(dāng)前地址信息
class 編程 js路由跳轉(zhuǎn)
history.push('/login');