react路由,4.x的差异还是比较大,暂时还是3.x的版本
安装:
npm install -S react-router@3.x
配置:
import { Router, Route, hashHistory } from 'react-router'; <Router history={hashHistory}>{/*browserHistory、hashHistory、createMemoryHistory*/} <Route exact path="/" component={App}> {/*exact 表示精确匹配*/} <IndexRoute component={Home}/>{/*显式指定Home是根路由的子组件,即指定默认情况下加载的子组件。*/} <IndexRedirect to="/welcome" />{/*IndexRedirect组件用于访问根路由的时候,将用户重定向到某个子组件。*/} <Route path="welcome" component={Welcome} /> <Route path="/repos" component={Repos}/> <Route path="/about/(:id)" component={About}/> <Route path="inbox" component={Inbox}> {/*<Redirect>组件用于路由的跳转,即用户访问一个路由,会自动跳转到另一个路由。*/} {/* 从 /inbox/messages/:id 跳转到 /messages/:id */} {/* :id 获取-> this.props.params.id*/} <Redirect from="messages/:id" to="/messages/:id" /> </Route> </Route> <Route path="*" component={Page404}></Route> </Router>
app组件:
export default React.createClass({ let baseUrl = this.props.match.url;{/*获得当前路由,即 / ,对于页面可维护性是十分重要的*/} render() { return ( <div> <ul role="nav"> <IndexLink to="/" activeClassName="active">Home</IndexLink>{/*默认页*/} <li><Link to=`/${baseUrl}/about` activeStyle={{color: 'red'}}>About</Link></li> <li><Link to="/repos" activeClassName="active">Repos</Link></li> <li><Link to={{ pathname: '/hello', query: { name: 'ryan' } }}> Hello </Link></li> <li><Link to={`/my/${myId}/info`}>点击</Link></li> <li><Link to={{pathname:"/select", hash:'#ahash', query:{foo: 'bar', boo:'boz'}, state:{data:'miao'} }} activeClassName="GlobalNav-active">精选</Link></li> </ul> <div> {this.props.children} {/*this.props.children属性就是子组件*/} </div> </div> ) } })
path属性:
<Route path="/hello/:name"> // 匹配 /hello/michael // 匹配 /hello/ryan <Route path="/hello(/:name)"> // 匹配 /hello // 匹配 /hello/michael // 匹配 /hello/ryan <Route path="/files/*.*"> // 匹配 /files/hello.jpg // 匹配 /files/hello.html <Route path="/files/*"> // 匹配 /files/ // 匹配 /files/a // 匹配 /files/a/b <Route path="/**/*.jpg"> // 匹配 /files/hello.jpg // 匹配 /files/path/to/file.jpg
path
属性也可以使用相对路径(不以/
开头),匹配时就会相对于父组件的路径。路由匹配规则是从上到下执行,一旦发现匹配,就不再其余的规则了。
编程式导航:
hashHistory
import { hashHistory } from 'React-router' ... ... hashHistory.push('mine') //传参 hashHistory.push({ pathname: 'good/details/'+this.state.id,//与路由表中配置相对应, query: { title:value.title, name:value.name }, }) ... ...
接收参数:
this.props.params.id this.props.location.query.title this.props.location.query.name
此外:
browserHistory
import { browserHistory } from 'react-router'; ... ... browserHistory.push('/some/path');
context
对象
class Example extends React.Component { constructor(props, context) { super(props, context); this.context.router; // it works } ... ... handleSubmit(event) { this.context.router.push(path) }, } //必须显示声明 Example.contextTypes = { router: React.PropsTypes.object }
路由钩子:
onEnter与onLeave
onEnter
钩子替代<Redirect>
组件。
<Route path="inbox" component={Inbox}> <Route path="messages/:id" onEnter={ ({params}, replace) => replace(`/messages/${params.id}`) } /> </Route>
onEnter
钩子还可以用来做认证。
const requireAuth = (nextState, replace) => { if (!auth.isAdmin()) { // Redirect to Home page if not an Admin replace({ pathname: '/' }) } } export const AdminRoutes = () => { return ( <Route path="/admin" component={Admin} onEnter={requireAuth} /> ) }
当用户离开一个路径的时候,跳出一个提示框,要求用户确认是否离开。
const Home = withRouter( React.createClass({ componentDidMount() { this.props.router.setRouteLeaveHook( this.props.route, this.routerWillLeave ) }, routerWillLeave(nextLocation) { // 返回 false 会继续停留当前页面, // 否则,返回一个字符串,会显示给用户,让其自己决定 if (!this.state.isSaved) return '确认要离开?'; }, }) )
上面代码中,setRouteLeaveHook
方法为Leave
钩子指定routerWillLeave
函数。该方法如果返回false
,将阻止路由的切换,否则就返回一个字符串,提示用户决定是否要切换。