React Router 一个针对React而设计的路由解决方案、可以友好的帮你解决React components 到URl之间的同步映射关系。此文版本react-router@^3.0.0
安装React-router:
npm install -s react-router
使用React-Router:
Router
组件本身只是一个容器,真正的路由要通过Route
组件定义。Route组件定义了URL与组件定义的关系,可以同时使用多个route组件。
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} />
<Route path="/example" component={Example} />
<Route path="/about" component={About} />
</Router>
), document.getElementById('container'))
dom:
<div id="container"></div>
上面代码中:跟路由http://localhost:9090/#/,加载home组件;访问http://localhost:9090/#/example加载Example组件;访问/about加载About组件。
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组件未完待续。