安装指令:
npm install react-router-dom --save
yarn add react-router-dom
使用:
import { BrowserRouter, Routes, Route, Link } from 'react-touter-dom'
BrowserRouter: 浏览器自带API,可以理解为一个盛放Route,Link的容器
Routes:提高路由匹配效率
Route:当前展示的视图
Link:指定跳转的路由
跳转方式:
编程式:useNavigate
导航式:Link
import { useNavigate } from 'react-router-dom'
<button onClikc = { () => useNavigate ('/home') } >跳转</button>
useNavigate ()只能在函数组件使用,class组件无法使用
若必须在class组件内使用,可以采取如下方法
import React,{ Component } from 'react'
import { useNavigate } from 'react-router-dom'
export function withNav(Component){
return () => <Component navigate={useNavigate()}/>
}
class hello extends Component{
constructor(props) {
super()
}
goBack = () => {
this.props.navigate('/home')
}
render() {
return(
<div>
<button onClick={()=>this.goBack()}>Back</button>
</div>
)
}
}
export default withNav(hello )
路由传参方式:
编程式:
1.<button onClikc = { () => useNavigate ('/home?id=2') } >跳转</button>
2.<button onClikc = { () => useNavigate ('/home/2') } >跳转</button>
路由内需要定义<Route path='/home/:id' component={Home}/>
声明式:
1.<Link to={ ` /index/100` }/> //传统字符串
2.<Link to={ ` /index/${id}` }/> //变量
3.<Link to={ { pathName:` /index/${id}`} }/> //传统字符串
4.<Link to={ ` /index/100` }/> //传统字符串
接收参数常用方式
1.useLocation //获取路由数据
import { useLocation} from 'react-router-dom'
const location = useLocation()
2.useParams //获取地址栏参数 比如 home/1
路由内需要定义<Route path='/home/:id' component={Home}/>
import { useParams } from 'react-router-dom'
const params= useParams ()
console.log(params.id) //1
3.useSearchParams //如 home?id=1&age=18
import { useSearchParams } from 'react-router-dom'
const [ getSearch //自定义 ]= useSearchParams ()
console.log(getSearch.getAll('id')) // id ==1
console.log(getSearch.getAll('age')) // id ==18
多级路由:
React内提供Outlet组件,将其用于 负组件中 可以为 子路由的 元素占位,并最终渲染子路 由的元素,嵌套路由可以保证 子路由共享父路由的界面不会再覆盖
比较拗口,通俗的理解就是,你的爸爸先去网吧玩,然后又帮你开了个机子占着
如:
<Route path='/manage' component={Manage}>
<Route path='/manage/system' component={System}>
</Route>
</Route>
这个时候需要再Manage页面内添加Outlet即可
import { Outlet } from 'react-router-dom'
render() {
return(
<div>
我的path是/manage,下面是为路由/manage/system 占位
<Outlet/>
</div>
)
}
常用的无限级路由 :
import Home from './home'
import Manage from './manage'
import System from './manage/system'
const routes =[
{
path:'/home',
element:Home
},
{
path:'/manage',
element:Manage,
children:[
{
path:'/manage/system',
element:System
},
]
}
]
function CreateRouter(){
return routes.map(route =>{
<Route key={route.path} path={route.path} component={route.element} />
{
route.children && CreateRouter( route.children )
}
</Route>
})
}
动态路由鉴权
function CreateRouter(){
return routes.map(route =>{
<Route
key={route.path}
path={route.path}
element={<auth
path={route.path}>
<route.element>
</auth>} />
{
route.children && CreateRouter( route.children )
}
</Route>
})
}
function auth(props){
const { children,path } = this.props;
if(path == '/home') return
const token = sessionStorage.getItem('token')
//没有token,登录
if(token){
return props.children
}else{
return <navigator to='/login'></navigator> //重定向
}
}
<Route path='/cinema' element={<auth> <Staff/> </auth>}}></Route>