1、路由基本使用
安裝模块
cnpm install react-router-dom -S
index.js中引入
import { HashRouter } from 'react-router-dom'
ReactDOM.render(
<React.StrictMode>
<HashRouter><App /></HashRouter>
</React.StrictMode>,
document.getElementById('root')
);
使用,引入
import { Link, Route } from 'react-router-dom'
import Home from './commonents/home'
import List from './commonents/list'
使用
<div className="App">
<div>
<Link to="/home">首页</Link>----
<Link to="/list">列表</Link>----
</div>
<div>
<Route path="/" component={ Home } exact />
<Route path="/home" component={ Home } />
<Route path="/list" component={ List } />
</div>
</div>
2 路由匹配规则
按照我们定义的Route从上到下依次匹配,.如果我们不小心定义了两个完全一样的路由,也会渲染两次,为了避免这种情况发生,我们可以使用Switch进行处理
import { Link, Route, Switch } from 'react-router-dom'
<Switch>
<Route path="/" component={ Home } exact />
<Route path="/home" component={ Home } />
<Route path="/list" component={ List } />
</Switch>
注意:/list/abc
这种的路由也会被/list
匹配到,如果不想被匹配到,需要添加属性exact.
如果我们想设置一个404的路由展示页,可以直接定义Route
,不设置path,只设置组件
<Route component={ NotFound } />
3 动态路由传参
在路由中添加动态路由参数
<Route path="/list/:id" component={ List } />
在组件获取参数,通過props属性值进行获取,this.props.match.params
render() {
console.log(this.props.match.params)
return (
<div className="List">
{ this.props.match.params.id }
</div>
);
}
4 查询参数传参
如果我们访问的链接为/home?title=123
,要想获取title的值,可以使用this.props.location.search
获取到查询参数?titile=123
,二次处理使用qs
模快
安装
cnpm install qs -S
使用以下方式,如果我們想要忽略?
,則可以设置属性ignoreQueryPrefix:true
let params = qs.parse(this.props.location.search, {ignoreQueryPrefix: true}
//param:{ "title" : 123 }
5 路由嵌套
例如:国内新闻是list组件下的嵌套路由,则可以使用${this.props.match}
来动态设置,避免因为一级路由的更改造成更高程度的更改.
return (
<div className="List">
<div>
<Link to={`${this.props.match.url}/inner`}>国内新闻</Link>
<Link to={`${this.props.match.url}/outer`}>国外新闻</Link>
</div>
<Route path={`${this.props.match.path}/inner`} component={Inner}/>
<Route path={`${this.props.match.path}/outer`} component={Outer} />
</div>
);
6 路由跳转及重定向
路由跳转
引入
import { createHashHistory } from 'history'
使用
<button onClick={() => { createHashHistory().push('/home') }}>回首页</button>
重定向
引入
import { Redirect } from 'react-router-dom'
重定向,适用场景,当用户在没有登录的情况下访问了需要登录的界面,需要重定向到登录界面
let isLogin = false
if(isLogin){
return <Redirect to="/home"></Redirect>
}
7 路由守卫
所谓的守卫就是在进入路由跳转之前进行的权限之类的判断等,如果判断通过,则展示相应的组件界面,如果没有通过,可以通过重定向的操作跳转到相应的权限界面
如果我们想在list组件加载之前进行一些路由的操作
定义auth
class Authorized {
constructor () {
this.authorized = false
}
login () {
this.authorized = true
}
logout () {
this.authorized = false
}
isAuthorized () {
return this.authorized
}
}
export default new Authorized()
引入auth,并在list加载之前判断是否是登录状态。使用Router中的render()
函数进行设置
<Route path="/list" render={(props) => {
console.log(auth.isAuthorized())
if (!auth.isAuthorized()) {
// 重定向
return <Redirect to="/home"></Redirect>
}else{
// 注意,参数传递形式
return <List {...props}></List>
}
}}/>
将守卫抽离
guard.js
import React, { Component } from 'react'
import auth from './auth'
import { Route, Redirect } from 'react-router-dom'
export default class AuthRouterGuard extends Component {
render(props) {
console.log(this.props)
const { Component, ...params } = this.props
console.log(params, '==============')
return (
<Route {...params} render={(props) => {
console.log(auth.isAuthorized())
if (!auth.isAuthorized()) {
// 重定向
return <Redirect to="/home"></Redirect>
} else {
// 注意,参数传递形式
return <Component {...params} {...props}/>
}
}} />
)
}
}
使用
import AuthRouterGuard from './commonents/guard'
<AuthRouterGuard path="/list" Component={ List } />
8 路由懒加载
有很多定义的模快,在我们刚进入页面的时候是没有看到的,但是对其进行了加载,延缓了加载速度,所以我们要使用懒加载对路由加载进行优化.
使用模块@/loadable/component
cnpm install @/loadable/component -S
使用loadComponent
方法,则组件在用到的时候才会进行懒加载
const Home = loadComponent( () => import('./commonents/home'))
const List = loadComponent( () => import('./commonents/list'))
const NotFound = loadComponent( () => import('./commonents/notFound'))
const auth = loadComponent( () => import('./commonents/auth'))
9,非路由组件传递路由信息
如果A组件中嵌套使用了B组件,但B组件并不作为路由组件出现,这个时候如果要吧A组件中接受到的路由信息数据传递给B组件,这种情况被称为非路由组件传递路由信息
使用withRoute
对组件进行包裹即可
import { withRouter } from 'react-router-dom'
export default widthRouter(B)