前言
- react-router-dom第六个版本对
route改动有点大,很多API都跟V5的使用方式不一样了,请注意
// 简单对比一下V5与V6的区别
<Switch> 重命名为 <Routes>
<Redirect> 重命名为 <Navigate>
`component/render` 被 `element` 替代
`useHistory` 被 `useNavigate` 替代
新API: `Outlet` - 主要用于子组件显示,作用类似于Vue中的`router-view`
- 下面介绍的关于路由都是以
V6版本为基准
目录结构介绍
app.js => { home, about => { subAbout, subAboutTwo }, dashboard }
动态路由
app.js
import { HashRouter as Router, Routes, Route, NavLink, Redirect } from 'react-router-dom'
import Home from './pages/home'
import About from './pages/about'
import Dashboard from './pages/dashboard'
function App() {
return (
<div className="App">
<div>
<NavLink to='/' exact="true">Home</NavLink>
<NavLink to='/about/*'>About</NavLink>
<NavLink to='/dashboard'>Dashboard</NavLink>
</div>
<Routes>
<Route exact path='/' element={<Home />}></Route>
<Route exact path='/about/*' element={<About />}></Route>
<Route exact path='/dashboard' element={<Dashboard />}></Route>
</Routes>
</div>
);
}
export default App;
【注意】`about` 路径应该指定一个通配符匹配器,以允许子路由`path="/about/*"`的继续匹配。
about.js
import React from 'react'
import { Link, Routes, Route } from 'react-router-dom'
import SubAbout from '../subAbout'
import SubAboutTwo from '../subAboutTwo'
const About = (props) => {
return (
<div>
<h1>About页面</h1>
<Link to='subAbout'>去subAbout</Link>
<Link to='subAboutTwo'>去subAboutTwo</Link>
<Routes>
<Route path='subAbout' element={<SubAbout />}>去subAbout</Route>
<Route path='subAboutTwo' element={<SubAboutTwo />}></Route>
</Routes>
</div>
)
}
export default About
【注意】二级路由的所有链接和路径也已更新为相对链接/路径而不是绝对链接/路径。
- Routes与Route搭配
- 这也是react-route-dom@v5对路由的一种设计理念
- 一级路由做统一集中配置和管理
- 二级路由在各自的children的父组件做配置和管理
实现效果
------------------------------------------ 分割线 ------------------------------------------
路由集中管理 + 懒加载
**
上述编写的路由太零散了,对于路由的管理不太友好。
可以参照 VUE 对路由进行集中管理
组件的加载也采用 -- 懒加载 -- 的方式
目录结构
src => router => index.js // 集中编写路由
router => index.js
import { lazy } from 'react'
const routes = [
{
path: '/',
name: 'Home',
exact: true,
element: lazy(() => import(('../pages/home'))),
children: []
},
{
path: '/dashboard',
name: 'Dashboard',
exact: true,
element: lazy(() => import(('../pages/dashboard'))),
children: []
},
{
path: '/about/*',
name: 'About',
exact: true,
element: lazy(() => import(('../pages/about'))),
children: [
{
path: 'subAboutOne',
name: 'SubAboutOne',
element: lazy(() => import(('../pages/subAbout'))),
},
{
path: 'subAboutTwo',
name: 'SubAboutTwo',
element: lazy(() => import(('../pages/subAboutTwo'))),
}
]
},
]
export default routes
app.js - 不管 children 的前提下
import { HashRouter as Router, Routes, Route, NavLink, Redirect } from 'react-router-dom'
import routes from './router'
import { React , Suspense } from 'react'
import { loadConfig } from 'browserslist';
function App() {
return (
<div className="App">
<div>
{
routes.map((route, index) => {
return (
<NavLink to={route.path} key={index}> { route.name } </NavLink>
)
})
}
</div>
<Routes>
{
routes.map((route, index) => {
return (
<Route exact={route.exact} path={route.path} element={
<Suspense fallback={
<div>Loading...</div>
}>
<route.element />
</Suspense>
} key={index}></Route>
)
})
}
</Routes>
</div>
);
}
export default App;
about.js - 不使用 Outlet 前提下
import React from 'react'
import { Link, Routes, Route, Outlet } from 'react-router-dom'
import SubAbout from '../subAbout'
import SubAboutTwo from '../subAboutTwo'
const About = (props) => {
return (
<div>
<h1>About页面</h1>
<Link to='subAboutOne'>去subAbout</Link>
<Link to='subAboutTwo'>去subAboutTwo</Link>
<Routes>
<Route path='subAboutOne' element={<SubAbout />}>去subAbout</Route>
<Route path='subAboutTwo' element={<SubAboutTwo />}></Route>
</Routes>
</div>
)
}
export default About
------------------------------------------ 分割线 ------------------------------------------
app.js - 循环遍历 children
import { HashRouter as Router, Routes, Route, NavLink, Navigate } from 'react-router-dom'
import routeItems from './router'
import { React , Suspense } from 'react'
function App() {
const routerViews = (routerItems) => {
if (routerItems && routerItems.length) {
console.log('routerItems ---- ', routerItems);
return routerItems.map(item => {
return item.children && item.children.length ? (
<Route key={item.path} path={item.path} element={
<Suspense fallback={<div>Loading...</div>}>
<item.element />
</Suspense>
}>
{routerViews(item.children)}
{
item.redirect ?
(
<Route path={item.path} element={<Navigate to={item.redirect} />}></Route>
) :
(
<Route path={item.path} element={<Navigate to={item.children[0].path} />}></Route>
)
}
</Route>
) : (
<Route key={item.path} path={item.path} element={
<Suspense fallback={<div>Loading...</div>}>
<item.element />
</Suspense>
}></Route>
)
})
}
}
return (
<div className="App">
<div>
<div>
{
routeItems.map((route, index) => {
return (
<NavLink to={route.path} key={index}> { route.name } </NavLink>
)
})
}
</div>
</div>
<Routes>
{
routerViews(routeItems)
}
</Routes>
</div>
);
}
export default App;
about.js - 使用 Outlet
import React from 'react'
import { Link, Routes, Route, Outlet } from 'react-router-dom'
const About = (props) => {
return (
<div>
<h1>About页面</h1>
<Link to='subAboutOne'>去subAbout</Link>
<Link to='subAboutTwo'>去subAboutTwo</Link>
<Outlet />
</div>
)
}
export default About
------------------------------------------ 分割线 ------------------------------------------
// 使用useRoutes的方法