react-router-domV6嵌套路由实现详解
摸鱼的汤姆 人气:0V6新特性
本片文章主要叙述react-router-dom v6版本基本使用介绍,下面开始梳理一下V6的新特性,以及嵌套路由的实现。
<Route>的属性变更component/render->element
// v5 <Route path='/login' component={<Suspense fallback={<Loading />}><Login /></Suspense>}> </Route> // v6 <Route path='/login' element={<Suspense fallback={<Loading />}><Login /></Suspense>}> </Route>
<Link/>使用变动
// 如果当前url为/home // V5 <Link to="page1"> -> <Link to="/page1"> // V6做法 <Link to="page1"> -> <Link to="/home/page1">
当前在 /home 我需要跳转到/home/page1,在V5中是存在路由歧义的,但是V6已经修复了
<Redirect/> 替换为 <Navigate/>
// v5 <Redirect to='/login'/> // v6 <Navigate to='/login' />
<Switch/> 重命名为 <Routes/>
// v5 // Suspense 异步加载 import {Switch,Router,Route} from 'react-router-dom' <Router> <Switch> <Route path='/login'> <Suspense fallback={<Loading />}><Login /></Suspense> </Route> <Route path='/*' > <Suspense fallback={<Loading />}><NotFound /></Suspense> </Route> </Switch> </Router> // v6 import {Routes,Router,Route} from 'react-router-dom' <Router> <Routes> <Route path='/login' element={<Suspense fallback={<Loading />}><Login /></Suspense>}> </Route> <Route path='/*' element={<Suspense fallback={<Loading />}><NotFound /></Suspense>}> </Route> </Routes> </Router>
V5中使用component或者render去渲染,或者被当做子组件渲染,但是在V6这些方法都已经element被淘汰
用useNavigate代替useHistory
// v5 let history = useHistory() history.push('/login'); history.replace('/login'); //v6 let navigate = useNavigate(); navigate('/login'); navigate('/login', {replace: true});
依赖包大小从20kb减少到8kb,整体体积减少
新钩子useRoutes代替react-router-config
function Page() { let pages = useRoutes([ { path: '/login', element:<Login/> }, // 404找不到 { path: '*', element: <NotFound /> } ]); return pages; }
新标签:<Outlet/>
<Content style={{ height: '90vh' }}> <Outlet></Outlet> </Content>
<Outlet/>
的出现帮我们节省了很多代码逻辑避免了多个< Routes />
,主要用于子组件显示,作用类似于Vue中的router-view
V6嵌套路由实现
- 路由配置routers.js
export const routerItems = [ { path:'/', Component:lazy(()=>import('./views/root')), redirect:'/designdraft', roles:[USER_ROLES.ADMIN,USER_ROLES.TEST], children:[ { path:'designdraft', Component:lazy(()=>import('./views/designdraft/index')), roles:[USER_ROLES.ADMIN], }, { path:'code', Component:lazy(()=>import('./views/code/index')), roles:[USER_ROLES.ADMIN], children:[], }, ] }, { path:'/login', Component:lazy(()=>import('./views/login')), children:[] }, { path:'*', Component:lazy(()=>import('./views/404')), children:[] } ]
- 嵌套路由组件封装
import{ Suspense,lazy, useEffect } from 'react'; import {routerItems } from '../routers'; // 引入 import { HashRouter as Router, Routes, Route, Navigate, } from 'react-router-dom'; // loading页面 const Loading = () => ( <> <div className='loadsvg'> <div> loading... </div> </div> </> ) // 递归函数 const rotuerViews = (routerItems)=>{ if(routerItems && routerItems.length){ return routerItems.map(({path,Component,children,redirect})=>{ return children && children.length ? ( <Route path={path} key={path} element={<Suspense fallback={<Loading/>}><Component/></Suspense>}> {rotuerViews(children)} // 递归遍历子路由 {redirect? (<Route path={path} element={<Navigate to={redirect} />}></Route>): (<Route path={path} element={<Navigate to={children[0].path} />}></Route>) } </Route> ):( <Route key={path} path={path} element={ <Suspense fallback={<Loading/>}><Component/></Suspense>}> </Route> ) }) } } const PageView = () => { return ( <Router> <Routes> {rotuerViews(routerItems)} </Routes> </Router> ) } export default PageView;
- 视图显示
class Rootpage extends React.Component { // 状态型组件 constructor(props) { super(props) } render() { // 页面嵌套路由需要通过,递归路由组件,判断是否存在redirect,进行路由重定向 let token = sessionStorage.getItem('keys'); return ( <> <div> // 路由跳转 <NavLink to="/designdraft" state="admin">designdraft</NavLink> <NavLink to="/code" state="admin">code</NavLink> </div> <div> // 子路由视图显示 <Outlet></Outlet> </div> </> ) } } export default Rootpage
- V5版本的路由嵌套在这里不再过多叙述了,如果你用React足够多,肯定会了解
React-Router-dom-V5
版本的嵌套是如何实现的
总结
React-Router-dom-V6
版本不管是在体积上还是在功能方面都做了很大的升级,例如上面嵌套路由的写法来看V6确实比V5明显要好很多,毕竟代码量上就减少了不少
加载全部内容