1. 路由的基本使用
-
明确好界面中的导航区、展示区
-
导航区的
a标签改为Link标签<Link to="/xxxxx">Demo</Link><Link to="/home">Home</Link> <Link to="/about">About</Link> -
展示区写
Route标签进行路径的匹配<Route path='/xxxx' component={Demo}/><Route path="/home" component={Home} /> <Route path="/about" component={About} /> -
<App>的最外侧包裹一个<BrowserRouter>或<HashRouter>ReactDOM.render( <BrowserRouter> <App /> </BrowserRouter>, document.getElementById('root') );
2. 路由组件与一般组件区别
-
写法不同
- 一般组件:
<Demo/> - 路由组件:
<Route path="/demo" component={Demo}/>
- 一般组件:
-
存放位置不同
- 一般组件:
components/ - 路由组件:
pages/
- 一般组件:
-
接收到的
props不同-
一般组件:写组件标签时传递了什么,就能收到什么
-
路由组件:接收到三个固定的属性
history: go: ƒ go(n) goBack: ƒ goBack() goForward: ƒ goForward() push: ƒ push(path, state) replace: ƒ replace(path, state) location: pathname: "/about" search: "" state: undefined match: params: {} path: "/about" url: "/about"
-
3. NavLink的使用
NavLink可以实现路由链接的高亮,通过activeClassName指定样式名。
<NavLink activeClassName="demo" to="/home">Home</NavLink>
<NavLink activeClassName="demo" to="/about">About</NavLink>
4. 二次封装NavLink
export default class MyNavLink extends Component {
render() {
return <NavLink activeClassName="active" {...this.props} />;
}
}
<MyNavLink to="/about">About</MyNavLink>
<MyNavLink to="/home">Home</MyNavLink>
5. Switch的使用
- 通常情况下,
path和component是一一对应的关系 Switch可以提高路由匹配效率(单一匹配),匹配成功后,就不继续往下遍历- 使用
<Switch></Switch>标签将<Route />包裹起来
<MyNavLink to="/about">About</MyNavLink>
<MyNavLink to="/home">Home</MyNavLink>
<Switch>
<Route path="/about" component={About} />
<Route path="/home" component={Home} />
</Switch>
6. 解决样式丢失问题
public/index.html中引入样式时不写./,写/(常用)public/index.html中 引入样式时不写./,写%PUBLIC_URL%(常用)- 使用
HashRouter
7. 严格匹配与模糊匹配
- 默认使用的是
模糊匹配(输入的路径必须包含要匹配的路径,且顺序要一致) - 开启严格匹配:
<Route exact={true} path="/about" component={About}/> - 严格匹配不要随便开启,需要再开。有些时候开启会导致无法继续匹配二级路由
8. Redirect的使用
一般写在所有路由注册的最下方,当所有路由都无法匹配时,跳转到Redirect指定的路由。
<Switch>
<Route path="/about" component={About} />
<Route path="/home" component={Home} />
<Redirect to="/home" />
</Switch>
9. 嵌套路由
-
在需要开启路由的组件的文件夹中,再创建组件
-
在组件中开启子路由,注册子路由时要写上父路由的
path值 -
路由的匹配是按照注册路由的顺序进行的
export default class Home extends Component {
render() {
return (
<div>
<h2>Home</h2>
<div>
<MyNavLink to="/home/news">News</MyNavLink>
<MyNavLink to="/home/message">Message</MyNavLink>
</div>
<div>
<Switch>
<Route path="/home/news" component={News} />
<Route path="/home/message" component={Message} />
<Redirect to="/home/news" />
</Switch>
</div>
</div>
);
}
}
10. 传递参数
详情请点击React-Router 传递参数。
11. push和replace的区别
push模式
路由可以理解为栈的数据结构,push模式下,将每一次的地址推入栈中,会形成history,可返回到上一层。
replace模式
replace模式下,将栈顶的地址替换为当前的地址,不会形成history,不可返回到上一层,因为上一层被替换了。
React-Router中默认是push模式,可在路由链接处开启replace模式:
<Link replace={true} to="/home/message/detail/id/title">title</Link>
12. 编程式路由导航
借助this.prosp.history对象上的API对操作路由跳转、前进、后退。
pushShow = (id, title) => {
// push+params
this.props.history.push(`/home/message/detail/${id}/${title}`);
// push+search
this.props.history.push(`/home/message/detail/?id=${id}&title=${title}`);
// push+state
this.props.history.push(`/home/message/detail/`, { id, title });
};
replaceShow = (id, title) => {
// replace+params
this.props.history.replace(`/home/message/detail/${id}/${title}`);
// replace+search
this.props.history.replace(`/home/message/detail/?id=${id}&title=${title}`);
// replace+state
this.props.history.replace(`/home/message/detail/`, { id, title });
};
...
<button onClick={() => {this.pushShow(msgObj.id, msgObj.title)}}>push模式</button>
<button onClick={() => {this.replaceShow(msgObj.id, msgObj.title);}}>replace模式</button>
13. withRouter的使用
withRouter可以加工一般组件,让一般组件具备路由组件的APIwithRouter返回值是一个新组件
import { withRouter } from 'react-router-dom';
...
class Header extends Component {
...
}
export default withRouter(Header);
14. BrowserRouter与HashRouter的区别
BrowserRouter | HashRouter | |
|---|---|---|
| 底层原理 | 使用H5的history API,不兼容IE9及以下版本 | 使用URL的哈希值,兼容性更好 |
path形式 | 路径中没有#,localhost:3000/demo/test | 路径包含#,localhost:3000/#/demo/test |
刷新后对路由state参数的影响 | 没有任何影响,因为state保存在history对象中 | 刷新后会导致路由state参数的丢失! |
备注:HashRouter可以用于解决一些路径错误相关的问题。