React Router 一個針對React而設計的路由解決方案、能夠友好的幫你解決React components 到URl之間的同步映射關係。此文版本react-router@^3.0.0css
安裝React-router:html
npm install -s react-router
使用React-Router:react
Router
組件自己只是一個容器,真正的路由要經過Route
組件定義。Route組件定義了URL與組件定義的關係,能夠同時使用多個route組件。npm
import { Router, Route, Link, hashHistory, IndexRoute, Redirect, IndexLink ,browserHistory } from 'react-router'瀏覽器
//導入組件
import home from './page/home/Home.jsx'
import Example from './page/Example/Example.jsx'
import About from './page/about/about.jsx'服務器
//配置路由 react-router
render((
<Router history={hashHistory} >
<Route path="/" component={Home} />
<Route path="/example" component={Example} />
<Route path="/about" component={About} />
</Router>
), document.getElementById('container'))app
dom:框架
<div id="container"></div>
上面代碼中:跟路由http://localhost:9090/#/,加載home組件;訪問http://localhost:9090/#/example加載Example組件;訪問/about加載About組件。dom
history:
用來監聽瀏覽器地址欄的變化,並將URL解析成一個地址對象,供 React Router 匹配
值:hashHistory、browserHistory、createMemoryHistory
hashHistory:不須要服務器配置,在URL生成一個哈希來跟蹤狀態。路由的切換由URL的hash變化決定,即URL的#部分發生變化。舉例來講,訪問http://localhost:9090,實際會看到的是http://localhost:9090/#/。
browserHistory:須要配置服務器,不然用戶直接向服務器請求某個子路由,會顯示網頁找不到的404錯誤。路徑是真是URL指向服務器資源,官方推薦。
createMemoryHistory主要用於服務器渲染。它建立一個內存中的history對象,不與瀏覽器URL互動。
const history = createMemoryHistory(location)
嵌套路由:
import { Router, Route, Link, hashHistory, IndexRoute, Redirect, IndexLink ,browserHistory } from 'react-router'
//導入組件
import home from './page/home/Home.jsx'
import Example from './page/Example/Example.jsx'
import about from './page/about/about.jsx'
<Router history={hashHistory}>
<Route path="/" component={App}>
<Route path="/home" component={Home}/>
<Route path="/example" component={Example}/>
<Route path="/about" component={About}/>
</Route>
</Router>
app組件得寫成這樣:
const ACTIVE = { color: 'red' }
class App extends React.Component {
render() {
return (
<div>
<div id="leftMenu" className="leftMenu">
<h1>個人路由</h1>
<ul>
<li><Link to="/home" activeStyle={ACTIVE}>首頁</Link></li>
<li><Link to="/example" activeStyle={ACTIVE}>案例</Link></li>{/*Link見下文*/}
<li><Link to="/about" activeStyle={ACTIVE}>關於</Link></li>
</ul>
</div>
<div id="rightWrap">
{ this.props.children }
</div>
</div>
)
}
}
css:
/*總體框架*/ #leftMenu { position: absolute; top: 0; left: 0; bottom: 0; background: #333; border-right: 1px solid #e9e9e9; width: 185px; } #rightWrap{ box-sizing: border-box; padding: 20px 20px 0; position: absolute; right: 0; bottom: 0; overflow-y: auto; top: 0; left: 185px; }
app組件中的this.props.children屬性就是子組件。
當用戶訪問/example,會先加載App組件,而後在它的內部再加載Example組件:
<App> <Example/>
</App>
IndexRoute組件:
上面嵌套路由的例子,訪問/home是沒問題,可是訪問根路徑/不會加載任何組件。App組件的this.props.children,這時是undefined。所以,一般會採用{this.props.children || <Home/>}這樣的寫法。Home明明是Example、About同級組件,卻沒有寫在Route中。
IndexRoute就是解決這個問題,顯式指定Home是根路由的子組件,即指定默認狀況下加載的子組件。能夠把IndexRoute想象成某個路徑的index.html。
import { Router, Route, Link, hashHistory, IndexRoute, Redirect, IndexLink ,browserHistory } from 'react-router' //導入組件 import home from './page/home/Home.jsx' import Example from './page/Example/Example.jsx' import about from './page/about/about.jsx' <Router history={hashHistory}> <Route path="/" component={App}> <IndexRoute component={Home}/> <Route path="/example" component={Example}/> <Route path="/about" component={About}/> </Route> </Router>
此時,用戶訪問/就會加載Home組件。
IndexRoute
組件沒有路徑參數path
。
Link:
組件用於取代<a>元素,生成一個連接,容許用戶點擊後跳轉到另外一個路由,能夠接收Router的狀態。activeStyle用於設置當前路由的樣式(被選中的路由)與其餘樣式不一樣。另外一種作法是,使用activeClassName指定當前路由的Class。
const ACTIVE = { color: 'red' }
<ul>
<li><Link to="/example" activeStyle={ACTIVE}>首頁</Link></li>
<li><Link to="/example" activeStyle={{color:'red'}}>首頁</Link></li>
<li><Link to="/about" className='active'>首頁</Link></li>
</ul>
若不使用Link須要導航到路由頁面:
import {hashHistory,browserHistory } from 'react-router' hashHistory.push('/about') browserHistory.push('/xxxxxx')
路由鉤子:
Enter
和Leave
鉤子,用戶進入或離開該路由時觸發。
import { Router, Route, Link, hashHistory, IndexRoute, Redirect, IndexLink ,browserHistory } from 'react-router' //導入組件 import home from './page/home/Home.jsx' import Example from './page/Example/Example.jsx' import About from './page/about/about.jsx' //配置路由 render(( <Router history={hashHistory} > <Route path="/" component={Home} onEnter={()=>console.log('進入頁面了')} onLeave={()=>console.log('離開頁面了')}/> <Route path="/example" component={Example} > <Route path="/about" component={About} /> </Router> ), document.getElementById('container'))
路由參數:
例:列表帶id跳轉到詳情
路由配置:
import { Router, Route, Link, hashHistory, IndexRoute, Redirect, IndexLink ,browserHistory } from 'react-router' //導入組件 import List from './page/List/list.jsx' import Detail from './page/Detail/detail.jsx' //配置路由 render(( <Router history={hashHistory} > <Route path="/list" component={List} > <Route path="/detail/:id" component={Detail} /> </Router> ), document.getElementById('container'))
列表點擊事件:
import { Router, Route, Link, hashHistory, IndexRoute, Redirect, IndexLink ,browserHistory } from 'react-router' <div> <li onClick={()=>{hashHistory.push(`/detail/${listData.id}`)}}>我是一條數據</li> </div>
詳情頁取得參數:
this.props.params.id
若帶了多了參數,也是用一樣的方法。
<Route path="/CustomerForm/demand/:demand/cusid/:cusid/espid/:espid" component={CustomerForm} />
//帶參數跳轉
<Link key={index} to={'/CustomerForm/demand/'+demand.id+'/cusid/'+cusid.id+'/espid/'+espid.id}>
點我過去
</Link>
//取參數
componentDidMount() { const demanid = this.props.params.demand; const cusid = this.props.params.cusid; const espid = this.props.params.espid; }
Redirect組件未完待續。