一.场景
单页应用可以根据路由去加载不同组件,在react中,官方有一个Router组件可以让我们做这个路由配置,实现不同路由去加载不同组件。
二.安装
这里选择react-router的4.x以上的版本,必须要安装react-router-dom。注意v4版本和之前的版本有较大区别。
npm install react-router-dom --save
三.引用Router
import {HashRouter as Router,Route,Link} from "react-router-dom";
HashRouter是指用hash做标识,就是url上的路由显示在/#/后面。另外一种BroswerRouter是直接带在url上。
Link是跳转路由用的组件,可以理解为a标签的组件。
四.配置路由
render() { return <Router> <ul> <li><Link to="/tab1">tab1</Link></li> <li><Link to="/tab2">tab2</Link></li> <li><Link to="/tab3">tab3</Link></li> </ul> <Route path="/tab1" component={Tab1} /> <Route path="/tab2" component={Tab2} /> <Route path="/tab3" component={Tab3} /> </Router>; }
点击对应Link,就可以跳转到对应组件。
五.包含式路由和exact关键字
和之前router版本不同的是,写入path后,之前版本是完全匹配的。而v4版本是会有包含关系,比如url输入"/tab2",那么就会匹配到path为"/"和path为"/tab2"的路由,同时将这些渲染出来。所以,v4版本多了个exact关键字,表示只对当前路由进行匹配。
render() { return <Router> <ul> <li><Link to="/">tab1</Link></li> <li><Link to="/tab2">tab2</Link></li> <li><Link to="/tab3">tab3</Link></li> </ul> <Route path="/" exact component={Tab1} /> <Route path="/tab2" component={Tab2} /> <Route path="/tab3" component={Tab3} /> </Router>; }
六.独立路由:switch
使用Switch组件,可以使路由只有一个被匹配到,并且总是渲染第一个匹配到的路由。
<Switch> <Route path="/" exact component={Tab1} /> <Route path="/tab2" component={Tab2} /> <Route path="/tab3" component={Tab3} /> </Switch>
七.嵌套路由
在v3版本中,嵌套路由是统一在路由组件中作嵌套配置的。
<Route path="/" component={Tab1} /> <Route path="/tab2" component={Tab2}> <Route path="/tab2/messages/:id" component={Message}></Route> </Route> <Route path="/tab3" component={Tab3} />
但在v4版本中,这种写法会出现warn警告,不再允许这种写法。需要在该路由下的component里嵌套路由。
<Route path="/" component={Tab1} /> <Route path="/tab2" component={Tab2} /> <Route path="/tab3" component={Tab3} /> //Tab2组件 render() { return <div> 我是tab2 <Route path="/tab2/messages/:id" component={Message}></Route> </div>; }
完整代码如下。
App.jsx
var React = require('react'); import { HashRouter as Router, Route, Link, Switch } from "react-router-dom"; import Home from './component/Home.jsx' import Tab1 from './component/Tab1.jsx' import Tab2 from './component/Tab2.jsx' import Tab3 from './component/Tab3.jsx' class App extends React.Component { constructor() { super(); } render() { return <Router> <Home> <Route path="/" component={Tab1} /> <Route path="/tab2" component={Tab2} /> <Route path="/tab3" component={Tab3} /> </Home> </Router>; } } export default App;
Home.jsx
var React = require('react'); import { HashRouter as Router, Route, Link } from "react-router-dom";' class Home extends React.Component { constructor(props) { super(props); } render() { return <div> <ul role="nav"> <li><Link to="/">tab1</Link></li> <li><Link to="/tab2">tab2</Link></li> <li><Link to="/tab3">tab3</Link></li> </ul> 父组件 {this.props.children} </div>; } } export default Home;
Tab1.jsx
var React = require('react'); class App extends React.Component { constructor() { super(); } render() { return <div> 我是tab1 </div>; } } export default App;
Tab2.jsx
var React = require('react'); import { HashRouter as Router, Route, Link } from "react-router-dom"; import Message from './Message.jsx'; class App extends React.Component { constructor(props) { super(props); } render() { return <div> 我是tab2 <Link to="/tab2/messages/233">click msg</Link> <Route path="/tab2/messages/:id" component={Message}></Route> </div>; } } export default App;
Tab3.jsx
var React = require('react'); class App extends React.Component { constructor() { super(); } render() { return <div> 我是tab3 </div>; } } export default App;
Message.jsx
var React = require('react'); class App extends React.Component { constructor(props) { super(props); this.state = { match: props.match } } render() { return <div> 我是message {this.state.match.params.id} </div>; } } export default App;