一、路由安装
- 路由官网
2021.11月初,react-router 更新到 v6 版本。
使用最广泛的 v5 版本的使用
npm i react-router-dom@5.3.0
二、路由使用
2.1 路由的简单使用
第一步 在根目录下 创建 views 文件夹 ,用于放置路由页面
films.js示例代码
export default function Films() {
return <div>films</div>
}
第二步 在根目录下 创建router文件夹,并新建indexRouter.js文件 用来管理路由
indexRouter.js 页面示例代码
//1.引入 hashrouter
import { HashRouter, Route } from 'react-router-dom'
import { Component } from 'react'
//2.引入组件
import Films from '../views/films'
import Cinemas from '../views/cinemas'
import Center from '../views/center'
export default class IndexRouter extends Component {
render() {
return (
//3 使用
<HashRouter>
<Route path="/films" component={Films}></Route>
<Route path="/cinemas" component={Cinemas}></Route>
<Route path="/center" component={Center}></Route>
</HashRouter>
)
}
}
第三步 在App.js中 引入indexRouter
App.js中示例代码
import IndexRouter from './router/indexRouter'
export default function App() {
return (
<div>
<IndexRouter></IndexRouter>
</div>
)
}
第四步 在入口文件index.js中渲染页面
index.js示例代码
import React from 'react'
import ReactDom from 'react-dom/client'
import App from './App.js'
ReactDom.createRoot(document.querySelector('#root')).render(<App></App>)
2.2 路由的重定向
第一步 引入Redirect
import { HashRouter, Route, Redirect } from 'react-router-dom'
第二步 使用 (模糊匹配)
默认模糊匹配
export default class IndexRouter extends Component {
render() {
return (
//3 使用
<HashRouter>
<Route path="/films" component={Films}></Route>
<Route path="/cinemas" component={Cinemas}></Route>
<Route path="/center" component={Center}></Route>
{/* 路由的重定向 模糊匹配*/}
<Redirect from="/" to="/films"></Redirect>
</HashRouter>
)
}
}
2.3 路由Switch组件与404页面
Switch组件
-
包裹 Route 组件,只会渲染第一个匹配的组件,即使有多个路由都可以匹配成功
在实际开发时,通常会用 Switch 组件包裹 Route 组件
通过 Switch 组件非常容易的就能实现 404 页面功能
-
需引入
import { HashRouter, Route, Redirect, Switch } from 'react-router-dom'
//switch 包裹router标签
<Switch>
<Route path="/films" component={Films}></Route>
....中间省略....
{/* 404页面 */}
<Route component={NotFound}></Route>
</Switch>
404 页面实现
1.views目录下新建notFound.js
2.路由indexRouter.js中引入
import NotFound from '../views/notFound'
3.使用
<HashRouter>
<Switch>
<Route path="/films" component={Films}></Route>
<Route path="/cinemas" component={Cinemas}></Route>
<Route path="/center" component={Center}></Route>
{/* 路由重定向 精确匹配 exact 必须外边用Switch标签包裹 */}
<Redirect from="/" to="/films" exact></Redirect>
{/* 404页面 */}
<Route component={NotFound}></Route>
</Switch>
2.4 路由嵌套
必须一级路由是模糊匹配!!!
1.新建二级路由页面,并在一级路由页面引入
2.一级路由页面配置路由信息
一级路由示例代码
//引入switch route
import { Switch, Route, Redirect } from 'react-router-dom'
//引入
import One from './films/one'
import Two from './films/two'
export default function Films() {
return (
<div>
films
<Switch>
<Route path="/films/one" component={One}></Route>
<Route path="/films/two" component={Two}></Route>
{/* 重定向 */}
<Redirect from="/films" to="/films/one"></Redirect>
</Switch>
</div>
)
}
2.5 声明式导航与编程式导航
2.5.1 声明式导航
通过 a链接 进行跳转
//需加 #
<a href="#/center">我的</a>
通过NavLink 进行跳转
//1.引入
import { NavLink } from 'react-router-dom'
....
<NavLink to="/center">我的</NavLink>
2.5.2 编程式导航
核心代码
import axios from 'axios'
import { useState, useEffect } from 'react'
import { useHistory } from 'react-router-dom'
export default function Tabbar(props) {
console.log('打印props', props)
let history = useHistory() //将useHistory()钩子赋值给history方便使用
const [list, setList] = useState([])
useEffect(() => {
axios
.get('http://localhost:3000/data.json')
.then((res) => {
console.log('接口请求成功', res)
setList(res.data.tabs)
})
.catch((err) => {
console.log('接口请求失败', err)
})
}, [])
const toDetails = (id) => {
console.log('编程式导航', id)
// 原生js 跳转
// window.location.href = 'http://localhost:3000/#/cinemas'
history.push(`/detail/${id}`)
}
return (
<>
<h1>编程式导航</h1>
<ul>
{list.map((item, index) => (
<li key={item.id} onClick={() => toDetails(item.id)}>
{item.name}
</li>
))}
</ul>
</>
)
}
2.6 路由传参
2.6.1 动态路由传参
核心代码
传递参数页面
import axios from 'axios'
import { useState, useEffect } from 'react'
import { NavLink, useHistory } from 'react-router-dom'
export default function Tabbar(props) {
console.log('打印props', props)
let history = useHistory() //将useHistory()钩子赋值给history方便使用
const [list, setList] = useState([])
useEffect(() => {
axios
.get('http://localhost:3000/data.json')
.then((res) => {
console.log('接口请求成功', res)
setList(res.data.tabs)
})
.catch((err) => {
console.log('接口请求失败', err)
})
}, [])
const toDetails = (id) => {
//1.history.push跳转传参
history.push(`/detail/${id}`)
}
return (
<>
<ul>
{list.map((item, index) => (
<li key={item.id} onClick={() => toDetails(item.id)}>
{item.name}
</li>
))}
</ul>
</>
)
}
路由页面
{/* 详情 :myid接参占位 */}
{/* history.push跳转传参 */}
<Route path="/detail/:myid" component={Detail}></Route>
接参页面
export default function Detail(props) {
// history.push跳转传参
console.log('详情', props.match.params.myid)
return <div>详情页面</div>
}
2.6.2 state传参
传递参数页面
import axios from 'axios'
import { useState, useEffect } from 'react'
import { useHistory } from 'react-router-dom'
export default function Tabbar(props) {
console.log('打印props', props)
let history = useHistory() //将useHistory()钩子赋值给history方便使用
const [list, setList] = useState([])
useEffect(() => {
axios
.get('http://localhost:3000/data.json')
.then((res) => {
console.log('接口请求成功', res)
setList(res.data.tabs)
})
.catch((err) => {
console.log('接口请求失败', err)
})
}, [])
const toDetails = (id) => {
//state传参
history.push({ pathname: '/detail', state: { myid: id } })
}
return (
<>
<ul>
{list.map((item, index) => (
<li key={item.id} onClick={() => toDetails(item.id)}>
{item.name}
</li>
))}
</ul>
</>
)
}
路由配置
<Route path="/detail" component={Detail}></Route>
接参页面
export default function Detail(props) {
//第二种传参
console.log('第二种传参', props.location.state.myid)
return <div>详情页面</div>
2.7 路由拦截
需求:没有token(未登录) 跳转到登录页面
1.定义函数 用于返回本地是否有token
isLogin() {
console.log('是否登录', localStorage.getItem('token'))
return localStorage.getItem('token')
}
2.创建登录页 并路由引入配置登录页
{/* 登录页面 */}
<Login path="/login" component={Login}></Login>
3.在需要判断的页面路由上 动态判断
//是否登录 登录跳转至该页面 未登录 重定向登录页面
<Route path="/center" render={() =>
this.isLogin() ? <Center /> : <Redirect to="/login"></Redirect>
}>
</Route>
2.8 路由模式
1.哈希模式 路径带# HashRouter
2.BrowserRouter 路径没有# 真正朝后端发请求
//引入BrowserRouter
import {
BrowserRouter as Router,
} from 'react-router-dom'
...
//使用
<Router>
<Switch>
...路由...
</Switch>
</Router>