經過官網咱們能夠發現 react-router
能夠用在 web 網站端
native 設備端
css
咱們這裏針對 web 網站端
安裝html
yarn add react-router-dom
react-router
會包自動依賴安裝前端
import React, {Component} from 'react' import {HashRouter as Router, Route, Link, Switch} from 'react-router-dom' const Home = () => ( <div> <h2>首頁</h2> </div> ) const About = () => ( <div> <h2>關於</h2> </div> ) class RouterView extends Component { render() { return ( <Router> <div> <ul> <li> <Link to="/">首頁</Link> </li> <li> <Link to="/about">關於</Link> </li> </ul> <Switch> <Route exact path="/" component={Home} /> <Route path="/about" component={About} /> </Switch> </div> </Router> ) } } export default RouterView
最外層須要包裹組件<Router>
組件<Route>
就是你看到的組件內容,放在哪裏就哪裏顯示
組件<Link>
是頁面連接
https://codepen.io/ducafecat/...html5
BrowserRouter
仍是 HashRouter
BrowserRouter
是須要服務端配合, 是基於html5的pushState和replaceState的,不少瀏覽器不支持,存在兼容性問題。
連接地址長這樣
http://localhost:3000/about
HashRouter
是瀏覽器端解析路由
連接地址長這樣
http://localhost:3000#/about
import {HashRouter as Router, Route, Link, Switch} from 'react-router-dom' //import {BrowserRouter as Router, Route, Link, Switch} from 'react-router-dom' <Router> ... </Router>
我用
as Router
作了別名,方便切換
<Route>
屬性 exact
徹底匹配<Route path="/about" component={About} />
exact=false
的時候 path
等於 /about
/about/me
都能匹配react
可是 exact=true
的時候 只匹配 path
等於 /about
git
<Route>
屬性 strict
末尾斜槓的匹配<Route strict path="/about/" component={About} />
當 strict=true
路由請求末尾必須帶 /
github
<Link>
生成路由連接web
to: string
路由地址字符串redux
<Link to="/about?me=haha">關於</Link>
to: object
路由對象segmentfault
<Link to={{ pathname: '/courses', search: '?sort=name', hash: '#the-hash', state: { fromDashboard: true }>關於</Link>
replace: bool
設置 true
替換瀏覽器對象 history
爲當前路由,按回退按鈕時會發現以前的路由被替換了
<NavLink>
生成路由連接的基礎上,若是是當前路由設置激活樣式
activeClassName: string
樣式名稱
<NavLink to="/about" activeClassName="selected">關於</NavLink>
activeStyle: object
樣式對象
<NavLink to="/about" activeStyle={{ fontWeight: 'bold', color: 'red' }}>關於</NavLink>
isActive: func
判斷函數
const checkIsActive = (match, location) => { if (!match) { return false } ... return true } <NavLink to="/about" isActive={checkIsActive}>關於</NavLink>
<Switch>
只渲染出第一個與當前訪問地址匹配的 <Route>
或 <Redirect>
不然你有幾個 <Route>
都會顯示
<Redirect>
路由重定向
<Switch> <Redirect from='/users/:id' to='/users/profile/:id'/> <Route path='/users/profile/:id' component={Profile}/> </Switch>
當請求 /users/:id
被重定向去 '/users/profile/:id'
from: string
須要匹配的將要被重定向路徑。
to: string
重定向的 URL 字符串
to: object
重定向的 location 對象
push: bool
若爲真,重定向操做將會把新地址加入到訪問歷史記錄裏面,而且沒法回退到前面的頁面。
<Prompt>
當用戶離開當前頁面前作出一些提示。
message: string
當用戶離開當前頁面時,設置的提示信息。
<Prompt message="肯定要離開?" />
message: func
當用戶離開當前頁面時,設置的回掉函數
<Prompt message={location => `肯定要去 ${location.pathname} ?`} />
when: bool
決定是否啓用 Prompt
<Route path="/topics/:topicId" component={Topic} />
:topicId
定義參數
const Topic = ({match}) => ( <div> <h3>參數: {match.params.topicId}</h3> </div> )
match.params
就是傳遞的參數
代碼
import React, {Component} from 'react' import {BrowserRouter as Router, Route, Link, Switch} from 'react-router-dom' const Topic = ({match}) => ( <div> <h3>參數: {match.params.topicId}</h3> </div> ) class RouterView extends Component { render() { return ( <Router> <div> <ul> <li> <Link to="/topics/rendering">Rendering with React</Link> </li> <li> <Link to="/topics/components">Components</Link> </li> <li> <Link to="/topics/props-v-state">Props v. State</Link> </li> </ul> <Switch> <Route path="/topics/:topicId" component={Topic} /> </Switch> </div> </Router> ) } } export default RouterView
動圖效果
代碼
import React, {Component} from 'react' import {BrowserRouter as Router, Route, Link, Switch} from 'react-router-dom' const Back = () => ( <div> <h2>首頁</h2> </div> ) const NoMatch = () => ( <div> <h2>沒有匹配</h2> </div> ) class RouterView extends Component { render() { return ( <Router> <div> <ul> <li> <Link to="/back">返回</Link> </li> <li> <Link to="/also/will/not/match">路由請求</Link> </li> </ul> <Switch> <Route path="/back" component={Back} /> <Route component={NoMatch} /> </Switch> </div> </Router> ) } } export default RouterView
在最下面寫個默認組件,都沒命中,就是這個了
動圖效果
在 react-route4
中嵌套要這樣寫
<Switch> <Route path="/article" component={ArticleList} /> <Route path="/article/:id" component={Article} /> <Route path="/article/:id/recommend" component={ArticleRecommend} /> </Switch>
寫成一排,業務以下
path | 組件 | 說明 |
---|---|---|
/article | ArticleList | 文章列表 |
/article/:id | Article | 文章 |
/article/:id/recommend | ArticleRecommend | 文章推薦 |
適合用來作權限檢查
Route
const isAuthenticated = true const PrivateRoute = ({ component: Component, ...rest }) => ( <Route {...rest} render={props => isAuthenticated ? ( <Component {...props} /> ) : ( <Redirect to={{ pathname: "/login", state: { from: props.location } }} /> ) } /> );
... <Route path="/public" component={Public} /> <Route path="/login" component={Login} /> <PrivateRoute path="/protected" component={Protected} />
這裏用到了 react-transition-group
庫
動圖效果
yarn add react-transition-group
css
文件 fade.css
.fade-enter { opacity: 0; z-index: 1; } .fade-enter-active { opacity: 1; transition: opacity 250ms ease-in; } .fade-exit { opacity: 0; }
名稱 | 說明 |
---|---|
fade-enter | 動畫啓動 |
fade-enter-active | 動畫激活 |
fade-exit | 動畫離開 |
其它動畫樣式名字能夠參考 css-transition
... import {TransitionGroup, CSSTransition} from 'react-transition-group' import './fade.css'
TransitionGroup, CSSTransition
必須導入
const styles = {} styles.fill = { position: 'relative', height: '200px', width: '500px' } styles.content = { ...styles.fill, top: '40px', textAlign: 'center', height: '120px' } styles.nav = { padding: 0, margin: 0, position: 'absolute', top: 0, height: '40px', width: '100%', display: 'flex' } styles.navItem = { textAlign: 'center', flex: 1, listStyleType: 'none', padding: '10px' } styles.hsl = { color: 'white', paddingTop: '20px', fontSize: '30px', height: '120px' } styles.rgb = { color: 'white', paddingTop: '20px', fontSize: '30px', height: '120px' }
這是 react
的樣式對象,固然你也能夠寫成 .css
文件
const NavLink = props => ( <li style={styles.navItem}> <Link {...props} style={{color: 'inherit'}} /> </li> )
// 切換區域 A const HSL = ({match: {params}}) => ( <div style={{ ...styles.fill, ...styles.hsl, background: `hsl(${params.h}, ${params.s}%, ${params.l}%)` }} > hsl({params.h}, {params.s}%, {params.l}%) </div> ) // 切換區域 B const RGB = ({match: {params}}) => ( <div style={{ ...styles.fill, ...styles.rgb, background: `rgb(${params.r}, ${params.g}, ${params.b})` }} > rgb({params.r}, {params.g}, {params.b}) </div> )
const RouterView = () => ( <Router> <Route render={({location}) => ( <div style={styles.fill}> <Route exact path="/" render={() => <Redirect to="/hsl/10/90/50" />} /> <ul style={styles.nav}> <NavLink to="/hsl/10/90/50">Red</NavLink> <NavLink to="/hsl/120/100/40">Green</NavLink> <NavLink to="/rgb/33/150/243">Blue</NavLink> <NavLink to="/rgb/240/98/146">Pink</NavLink> </ul> <div style={styles.content}> <TransitionGroup> <CSSTransition key={location.key} classNames="fade" timeout={300}> <Switch location={location}> <Route exact path="/hsl/:h/:s/:l" component={HSL} /> <Route exact path="/rgb/:r/:g/:b" component={RGB} /> <Route render={() => <div>Not Found</div>} /> </Switch> </CSSTransition> </TransitionGroup> </div> </div> )} /> </Router> )
https://codepen.io/ducafecat/...