react-router
react路由
* 1.下载安装:
npm i react-router-dom
或
yarn add react-router-dom
* 2.路由的基本使用:
import React from "react";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
export default function App()
{
return
( <Router> <div> <nav> <ul>
<li> <Link to="/">Home</Link> </li>
<li> <Link to="/about">About</Link> </li>
<li><Link to="/users">Users</Link> </li> </ul> </nav>
{/* A <Switch> looks through its children <Route>s and renders the first one that matches the current URL. */}
<Switch>
<Route path="/about" component={About}></Route>
<Route path="/users" component={Users}></Route>
<Route path="/" component={Home}></Route>
</Switch>
</div>
</Router>
);}
function Home () { return <h2>Home</h2>; }
function About() { return <h2>About</h2>; }
function Users() { return <h2>Users</h2>; }
路由定义
根据不同的地址呈现对应得页面,叫路由。
react 路由匹配模式是贪婪模式
当地址栏发生改变,BrowserRouter 里的所有导航和 Route 都会被触发匹配
路由组成部分
路由容器
BrowserRouter [h5api] 和 HashRouter [#的]
props:basename 设置一个基础根路由
Router
包裹路由的容器,放在最外层
Route
表示路由组件(每一个路由)
1.path表示路由的路径 /home => 去home的路径
2.component:表示路由对应的组件
3.路由上的属性通过props传递
4.路由模式
- HashRouter hash模式的路由 带#
- BrowserRouter history模式的路由
5.Route属性
- exact :精确匹配,默认是true
- strict :严格模式 必须/about这样访问
- sensitive : 严格大小写匹配
6.路径参数:/pathName/:值, /user/1
- 路径参数会传递到组件的props里面,路由所有的 props (mathch,location and history)会传递到组件里
- props.history 放的是路由的跳转方法
- props.go() push() 跳转到那个路由
- props.goBack() 后退
- props.goForward() 前进
7. 比如 根据多个用户的id访问用户详情 /user/:id :id 不固定但是必须传
8.render :function(){} 替代react组件渲染
1.render替代react组件渲染 <Route path="/lili" render={props => { function toLogin() { props.history.push("/login"); } return isLogin ? ( <Lili></Lili> ) : ( <button onClick={toLogin}>请登录</button> ); }} > </Route>
导航组件 Link和NavLink Redirect 重定向组件
1.Link
相当于a,to 匹配到的是path
1).to:string to="/"
2).to:object <link to={{pathname:"/courses" ,}} 方便传参
- pathname: 表示要链接到的路径的字符串。
- search: 表示查询参数的字符串形式。
- hash: 放入网址的 hash,例如 #a-hash。
- state: 状态持续到 location。通常用于隐式传参(埋点),可以用来统计页面来源
3).to:function <link to={location =>`${location.pathname} ? name=lili`}>
<Link to={location => `${location.pathname}?nam=lili`} />
2.Redirect 会导航到指定位置 to
3. NavLink
- activeClassName="" 激活class
- activeStyle=" " 激活样式
- exact 精确匹配
- strict 严格
* 激活的navlink会自动添加类名 .active如果设置了activeClassName 则不生效
* 根据多个用户id访问用户详情 不固定但是必须传 参数会传到组件的props.match.params上 例如 props.match.params.id
匹配组件
Route,匹配路由地址并渲染对应得页面组件
props:path[可选,通配符*表示匹配所有]、component[类组件和函数组件]>render[函数组件]>children[函数组件]
重定向组件
`<Redirect from="/当前地址" to="/要去的地址" />`
to:对象配置{pathname:"/dir",state:{},hash:""}
withRouter
高级函数:用于将非路由组件,进行包装,使该组件拥有路由的信息对象
Switch
什么时候使用 switch?
当使用 Redirect 重定向的时候使用。
功能:自上而下,逐一匹配,只要匹配上一条,立即渲染且终止向下匹配。
路由拦截器
prompt
```js import {Prompt } from "react-router-dom"; <Prompt message="您确定要离开该页面吗?" when={this.state.isOpen} /> <Prompt message = {() => { this.state.isOpen? false: "您确定要离开该页面吗?" }} /> ```
- 路由拦截的两个参数分别有什么作用
message:string。设置 Prompt 提示内容
message:function。此时返回参数分为 true/false。返回 false 就继续停留在当前页面,返回 true 则跳转到新页面。
when:设置是否启用 Prompt 功能
路由传参方式
1.search 相当于 vue 里的 query。地址栏以?key=value [location]
2. hash 锚点方式 [location]
3. state 通过 js 传参,数据类型为对象 [location]
4. params 通过动态路由传递数据 [match 对象]
路由配置方式
嵌套路由
一级导航视图里呈现二级的路由页面。二级的路由地址是基于一级的路由地址。
`/home 是一级,/home/01是嵌套的二级`
动态路由
一个匹配组件可以匹配到多个导航地址。和嵌套路由很相似,但是嵌套路由的地址是写死的,动态路由地址是被动态参数接收的
`/:id 可以匹配 /home,/news`
并且动态路由也是路由传参的一种方式
match的path
路由组件中被注入的对象,match 里有 path 属性和 url 属性。
path 地址是路由匹配用的。
url 指当前地址栏的路径。
如果需要在动态路由组件中拼接导航用 url,拼接 Route 用 path。
释放react的配置项
npm run eject
慎用!一旦释放,无法回退
每个组件文件都要引入 React
Lazy懒加载
react.lazy Suspense 代码分割 懒加载 (组件和路由都可)
* 懒加载只进行一次
*1.import React, { lazy, Suspense } from "react";
*2.组件或路由的引入方式 const Lilei = lazy(() => import("./authrouter/Lilei.js"));
*3.Suspense :用来包裹需要懒加载的路由或组件 不能单独包裹组件
fallback :组件未加载之前现实的内容
<Suspense fallback={<div>loading...</div>}>
<div>需要懒加载的组件</div>
</Suspense>
路由hooks
使用以下hooks 你的react版本需要是16.8及以上
- useHistory 路由跳转
- useParams 使用路径参数
- useLocation 获取当前路由信息
- useRouteMatch 用来匹配路由,必须匹配路径参数,不然获取不到,参数同route
import React from "react";
import { useRouteMatch } from "react-router-dom";
function Blog(props) {
return (
<div>
Blog
{props.match.params.title}
</div>
); } function Notfound() {
return "notfound"; }
// http://localhost:3000/Blog/:1
sensitive 大小写敏感 function Showblog()
{
let match = useRouteMatch({
path: "/blog/:title",
sensitive: true
});
return match ? <Blog match={match}></Blog> : <Notfound></Notfound>; }
export default Showblog;
import React from "react";
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
// Some folks find value in a centralized route config.
// A route config is just data. React is great at mapping
// data into components, and <Route> is a component.
// Our route config is just an array of logical "routes"
// with `path` and `component` props, ordered the same
// way you'd do inside a `<Switch>`.
const routes = [ { path: "/sandwiches", component: Sandwiches },
{ path: "/tacos", component: Tacos,
routes: [ { path: "/tacos/bus", component: Bus }, { path: "/tacos/cart", component: Cart } ] } ];
export default function RouteConfigExample() {
return (
<Router>
<div>
<ul>
<li>
<Link to="/tacos">Tacos</Link>
</li>
<li>
<Link to="/sandwiches">Sandwiches</Link>
</li>
</ul>
<Switch>
{routes.map((route, i) => ( <RouteWithSubRoutes key={i} {...route} /> ))} </Switch> </div> </Router> ); }
// A special wrapper for <Route> that knows how to
// handle "sub"-routes by passing them in a `routes`
// prop to the component it renders.
// 定义带子路由的组件如何渲染 function RouteWithSubRoutes(route) { return ( <Route path={route.path} render={props => (
// pass the sub-routes down to keep nesting <route.component {...props} routes={route.routes} /> )} /> ); }
function Sandwiches() { return <h2>Sandwiches</h2>; }
function Tacos({ routes }) {
return ( <div>
<h2>Tacos</h2> <ul> <li> <Link to="/tacos/bus">Bus</Link> </li> <li>
<Link to="/tacos/cart">Cart</Link> </li> </ul> <Switch>
{routes.map((route, i) => ( <RouteWithSubRoutes key={i} {...route} /> ))} </Switch> </div> ); }
function Bus() { return <h3>Bus</h3>; } function Cart() { return <h3>Cart</h3>; }
受保护的路由
- 使用render函数
<Route path="/lili"
render ={(props)=>{
function login(){
props.history.push('/login')
}
//判断登录状态来进行页面跳转 return isLogin?<Lili></Lili>:<button onClick={login}>请登录</button> }}> </Route>
- 使用高阶组件
import React from "react";
import { BrowserRouter as Router, Route, Link, Redirect, withRouter } from "react-router-dom";
// 1. Click the public page
// 2. Click the protected page
// 3. Log in
// 4. Click the back button, note the URL each time const AuthExample = () => (
<Router>
<div>
<AuthButton />
<ul>
<li>
<Link to="/public">Public Page</Link>
</li>
<li>
<Link to="/protected">Protected Page</Link>
</li>
</ul>
<Route path="/public" component={Public} />
<Route path="/login" component={Login} />
<PrivateRoute path="/protected" component={Protected} />
</div>
</Router> );
const fakeAuth = {
isAuthenticated: false,
authenticate(cb) {
this.isAuthenticated = true;
setTimeout(cb, 100);
// fake async
},
signout(cb) {
this.isAuthenticated = false;
setTimeout(cb, 100); } };
const AuthButton = withRouter(
({ history }) => fakeAuth.isAuthenticated ? ( <p> Welcome!{" "} <button onClick={() => { fakeAuth.signout(() => history.push("/")); }} >
Sign out </button> </p> ) : ( <p>You are not logged in.</p> ) );
const PrivateRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={props => fakeAuth.isAuthenticated ?
( <Component {...props} /> ) :
( <Redirect to={{ pathname: "/login", state: { from: props.location } }} /> ) } /> );
const Public = () => <h3>Public</h3>;
const Protected = () => <h3>Protected</h3>;
class Login extends React.Component {
state = { redirectToReferrer: false };
login = () => { fakeAuth.authenticate(() => { this.setState({ redirectToReferrer: true }); }); };
render() { const { from } = this.props.location.state || { from: { pathname: "/" } };
const { redirectToReferrer } = this.state;
if (redirectToReferrer) { return <Redirect to={from} />; }
return ( <div> <p>You must log in to view the page at {from.pathname}</p> <button onClick={this.login}>Log in</button> </div> ); } }
export default AuthExample;
路由过渡动画
1.下载:yarn add react-transition-group / npm i
2.引入组件
import { TransitionGroup, CSSTransition } from "react-transition-group";
3.把所有rout组件用一个小route包裹,用render函数的方式把所有
考试总结
## 路由定义
根据不同的地址呈现对应得页面,叫路由。
react 路由匹配模式是贪婪模式
当地址栏发生改变,BrowserRouter 里的所有导航和 Route 都会被触发匹配
## 路由组成部分
1. 路由容器 BrowserRouter [h5api] 和 HashRouter [#的]
2) 导航组件:Link、Navlink
3. 路由匹配组件:Route
## 路由传参方式
1. search 相当于 vue 里的 query。地址栏以?key=value [location]
2. hash 锚点方式 [location]
3. state 通过 js 传参,数据类型为对象 [location]
4. params 通过动态路由传递数据 [match]
## 路由跳转方式
- 导航跳转
- js 使用 props.history
## 路由配置方式
### 嵌套路由
一级导航视图里呈现二级的路由页面。二级的路由地址是基于一级的路由地址。
`/home 是一级,/home/01是嵌套的二级`
### 动态路由
一个匹配组件可以匹配到多个导航地址。和嵌套路由很相似,但是嵌套路由的地址是写死的,动态路由地址是被动态参数接收的
`/:id 可以匹配 /home,/news`
并且动态路由也是路由传参的一种方式
## 重定向组件
`<Redirect from="/当前地址" to="/要去的地址" />` - to:对象配置{pathname:"/dir",state:{},hash:""}
## withRouter
高级函数:用于将非路由组件,进行包装,使该组件拥有路由的信息对象。
什么时候使用 switch?
当使用 Redirect 重定向的时候使用。
功能:自上而下,逐一匹配,只要匹配上一条,立即渲染且终止向下匹配。
## react 路由拦截有几种方式
1) getUserConfirmation 只有页面刷新时才会触发
2) Prompt 当用户要离开页面时提示用户
prompt
```js import {Prompt } from "react-router-dom"; <Prompt message="您确定要离开该页面吗?" when={this.state.isOpen} /> <Prompt message = {() => { this.state.isOpen? false: "您确定要离开该页面吗?" }} /> ```
message:string。设置 Prompt 提示内容
message:function。此时返回参数分为 true/false。返回 false 就继续停留在当前页面,返回 true 则跳转到新页面。
when:设置是否启用 Prompt 功能
- 路由拦截的两个参数分别有什么作用
location:路由跳转地址
action:路由跳转方式
## 懒加载示例代码
```js import React, { lazy, Suspense } from "react"; const Home = lazy(() => import("../component/home")); const News = lazy(() => import("../component/news")); const routers = [ { path: "/home", label: "首页", component: props => ( <Suspense fallback='正在加载'> <Home {...props} /> </Suspense> ) }, { path: "/news", label: "新闻", component: props => ( <Suspense fallback='正在加载'> <News {...props} /> </Suspense> ) } ]; export default routers; ```
浙公网安备 33010602011771号