1、相关组件使用
- BrowserRouter/HashRouter:是一个路由容器,所有的路由组件(Route)都要放置在该组件内部,使用as可以设置一个别名。BrowserRouter没有#,HashRouter有#。
- Link:导航链接,相当于a标签
- Route:用于匹配路由组件
- Switch:只要匹配到一个地址不往下匹配,相当于for循环里面的break
- exact : 精确匹配路由
2、路由跳转
//router.js
import { BrowserRouter as Router, Link, Route, Switch } from "react-router-dom";
<Router>
<Switch>
<Route path="/" exact component={Index}></Route>
<Route path="/about" component={About}></Route>
<Route path="/user" component={User}></Route>
</Switch>
<ul>
<li><Link to="/">首页</Link></li>
<li><Link to="/about">关注我们</Link></li>
<li><Link to="/user">个人中心</Link></li>
</ul>
</Router>
3、路由传参
(1)在Link的to属性中传递
//声明要传递的参数
<Route path="/news/detail/:id/:title" component={NewsDetailPage}></Route>
//传递参数值
<Link to="/news/detail/1/新闻详情页1">新闻详情页1</Link>
//在组件内部获取参数
<h2>{this.props.match.params.id}---{this.props.match.params.title}</h2>
(2)通过事件函数添加(页面一刷新就报错!)
//通过事件函数添加参数时,不需要声明变量
<Route path="/news/detail" component={NewsPage}></Route>
//在事件函数中,将参数添加到props.history中保存
<li onClick={() => {
this.props.history.push({
pathname: '/news/detail',
search: "?id=2&title=新闻详情2",
query: {
id: 2,
title: "新闻详情2"
}
})
}}>新闻详情2</li>
//通过props.location来获取参数
<h2>{this.props.location.query.id}</h2>
(3)自定义函数接收(强烈推荐!!!)
//assets/js/utils.js
export default function localParam(search, hash) {
search = search || window.location.search;
hash = hash || window.location.hash;
var fn = function (str, reg) {
if (str) {
var data = {};
str.replace(reg, function ($0, $1, $2, $3) {
data[$1] = $3;
});
return data;
}
};
return {
search: fn(search, new RegExp("([^?=&]+)(=([^&]*))?", "g")) || {},
hash: fn(hash, new RegExp("([^#=&]+)(=([^&]*))?", "g")) || {}
};
}
<Route path="/news/detail" component={NewsPage}></Route>
//自定义函数接收参数:通过props.history将参数传递组件中
<li onClick={() => {
this.props.history.push("/news/detail?id=2&title=新闻详情3")
}}>新闻详情3</li>
//通过自定义函数处理参数,参数被保存在props.location中
<h2>{localParam(this.props.location.search).search.id}</h2>
<h2>{decodeURI(localParam(this.props.location.search).search.title)}</h2>
4、嵌套路由
嵌套路由时父路由不能使用精准匹配
//父路由 router.js
import GoodsIndex from "../pages/goods/index";
<Route path="/goods" component={GoodsIndex}></Route>
//子路由 index.js
<Router>
<ul>
<li><Link to="/goods/item">商品</Link></li>
<li><Link to="/goods/review">评价</Link></li>
<li><Link to="/goods/detail">详情</Link></li>
<li><Link to="/goods/recommend">推荐</Link></li>
</ul>
<Switch>
<Route path="/goods/item" component={ItemPage}></Route>
<Route path="/goods/review" component={ReviewPage}></Route>
<Route path="/goods/detail" component={DetailPage}></Route>
<Route path="/goods/recommend" component={RecommendPage}></Route>
//通过重定向显示默认的子组件,先有path再有重定向
<Redirect to="/goods/detail"></Redirect>
</Switch>
</Router>
5、路由认证
//制作会员认证路由
import AuthRoute from "../components/AuthRoute";
<AuthRoute path="/user" component={UserPage}></AuthRoute>
//components/AuthRoute.js
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
//登录验证,相当于vue守卫
export default function AuthRoute({ component: Component, ...rest }) {
return (
<Route {...rest} render={props =>
Boolean(localStorage['isLogin']) ? (
<Component {...props} />
) : (
<Redirect
to={{
pathname: "/login",
state: { from: props.location }
}}
/>
)
}
/>
);
}